zoukankan      html  css  js  c++  java
  • CF1452F Divide Powers 题解

    Codeforces
    Luogu

    Description.

    有一个长度为 \(n (n\le 30)\) 的序列,第 \(i\) 个是 \(a_i\)
    你每次可以选择一个 \(i\in[2,n]\),使得 \(a_i\leftarrow a_i-1,a_{i-1}\leftarrow a_{i-1}+2\)
    问使得 \(\sum_{i=1}^xa_i\ge K\) 的最小操作次数。

    Solution.

    考虑分类,\(i\le x\)\(i>x\)
    如果 \(i\le x\),那每次可以花一步代价使得答案加一。
    如果 \(i>x\),那每次可以花 \(2^{x-i}-1\) 步使得答案加 \(2^{x-i}\)
    长远考虑肯定是第二种操作更优,且第二种操作中肯定 \(x\) 越小效率越高。
    所以从 \(x+1\) 开始能操作满就操作,这样贪心正确性显然。
    直到一个地方不能操作满了,那就结束。
    接下来,相当于有两种决策,且没有完全最优性。
    可以考虑第一种操作枚举到哪里了。
    考虑一个 \(2^n\) 每次拆成两个,如果减地动肯定要贪心减。
    然后每次直接取最小值即可。
    然后直接 \(O(n)\) 扫描即可。

    Coding.

    点击查看局若代码
    //是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了{{{
    #include<bits/stdc++.h>
    using namespace std;typedef long long ll;
    template<typename T>inline void read(T &x)
    {
    	x=0;char c=getchar(),f=0;
    	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
    	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
    	f?x=-x:x;
    }
    template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
    int n,Q,cn[35];
    int main()
    {
    	read(n,Q);for(int i=0;i<n;i++) read(cn[i]);
    	for(int fg,x;Q--;)
    	{
    		ll k;read(fg,x,k);if(fg&1) {cn[x]=k;continue;}
    		int sm=0;ll rs=0;for(int i=0;i<=x;i++) sm+=cn[i];
    		if(sm>=k) {printf("%d\n",0);continue;}else k-=sm;
    		ll tt=0;for(int i=1;i<=x;i++) tt+=((1ll<<i)-1)*cn[i];
    		ll wj=0;for(int i=0;i<n;i++) wj+=(1ll<<i)*cn[i];
    		if(wj<k) {puts("-1");continue;}
    		int jc=0;for(int i=x+1;i<n;i++)
    		{
    			int lf=min(1ll*cn[i],k>>(i-x));k-=(1ll<<(i-x))*lf;
    			rs+=1ll*lf*((1ll<<(i-x))-1),tt+=((1ll<<i)-(1ll<<(i-x)))*lf;
    			if(lf<cn[i]) {jc=i;break;}
    		}if(k==0) {printf("%lld\n",rs);continue;}
    		if(jc==0) {printf("%lld\n",tt>=k?rs+k:-1ll);continue;}
    		ll as=1e18;for(int i=jc;i>x;)
    		{
    			if(tt>=k) as=min(as,rs+k);
    			rs++,i--;if(k>=(1ll<<(i-x)))
    				rs+=(1ll<<(i-x))-1,k-=1ll<<(i-x),tt+=((1ll<<i)-(1ll<<(i-x)));
    		}printf("%lld\n",min(as,rs));
    	}
    	return 0;
    }
    
  • 相关阅读:
    JavaScript中的memorizing技术
    在IE6/7/8下识别html5标签
    JavaScript中的类式继承和原型式继承
    OpenSUSE环境配置
    CentOS环境配置(LNMP)
    CentOS上OpenCC中文简繁体转换
    jQuery点击按钮页面滚动条向下滚动
    javascript-数组常用方法
    Tomcat配置常见错误问题解决方法
    字符串
  • 原文地址:https://www.cnblogs.com/pealfrog/p/15265141.html
Copyright © 2011-2022 走看看