CF 633 DIV2 C
题意:给你一个数组,你可以对数组里的任意元素进行如下操作:
在第X秒,你可以任意多个元素加上2^(x-1) ,注意:你也可以一个都不选,即第X秒pass掉。
问你X取多少时可以使得数组是非递减的。要你求X的最小值。
思路:我们把2的次方写出来 1,2,4,8,16……很容易(其实一点也不容易)发现这些数可以组成所有正整数。再说细致一点,就是当x=n时,前x-1秒内的2^(x-1)可以组成1到2^x-1中的所有数。
这么一来我们就可以得出一个结论,如果a i > a i+1 一定可以使a i+1 == a i 所以答案也就得出来了。
//author CN.TTDragon #include<bits/stdc++.h> typedef long long ll; const ll mod=1e9+7; const ll maxn=1e5+7; const double pi=acos(-1); using namespace std; ll a[maxn]={0};
//快速幂,防止pow的各种谜之问题 ll qp(int a,int b) { ll ret=1; while(b) { if(b&1) { ret=ret*a; } a=a*a; b>>=1; } return ret; }
int main() { int t; cin>>t; while(t--) { int n; cin>>n; memset(a,0,sizeof(a)); int mxsecond=0;//这个是最大的秒数 cin>>a[0]; int cnt=1;int jichu=0; for(int i=1;i<n;i++) { cin>>a[i]; jichu=a[i];//这里很重要的,如果a[i]>a[i-1],下面那个if就没意义了 cnt=1; while(a[i]<a[i-1]) { a[i]+=qp(2,cnt-1); mxsecond=max(cnt,mxsecond); cnt++; }
//经过一通加法后,a[i]会>=a[i-1],但是我们前面提到了,这些2的次方的和是可以组成所有数的。
//这里我们不妨把它们减去(注意这个减只是不加的意思,不是真正意义上的减),然它们相等,以减少下一个数的负担。
//如果a[i]天生就比a[i-1]大,那我们是不能减的。 if(a[i]>a[i-1]&&jichu<a[i-1]) { a[i]=a[i-1]; } } /*for(int i=0;i<n;i++) { cout<<a[i]<<" "; }*/ //cout<<endl; cout<<mxsecond<<endl; } return 0; }
写在最后:
第一次在DIV2中写出三道题,写完的时候超级开心~ 来到了青名,希望自己以后再接再厉。能早日AK比赛~
这篇文章就当一个纪念吧~
关注了很多大佬,希望能把每次不会的题补好吧~拼命不咕~
PS :数论TAG是乱加的~

浙公网安备 33010602011771号