Codeforces Round #633 (Div. 2) C. Powered Addition(贪心/二进制分解)
You have an array aa of length nn . For every positive integer xx you are going to perform the following operation during the xx -th second:
- Select some distinct indices i1,i2,…,iki1,i2,…,ik which are between 11 and nn inclusive, and add 2x−12x−1 to each corresponding position of aa . Formally, aij:=aij+2x−1aij:=aij+2x−1 for j=1,2,…,kj=1,2,…,k . Note that you are allowed to not select any indices at all.
You have to make aa nondecreasing as fast as possible. Find the smallest number TT such that you can make the array nondecreasing after at most TT seconds.
Array aa is nondecreasing if and only if a1≤a2≤…≤ana1≤a2≤…≤an .
You have to answer tt independent test cases.
The first line contains a single integer tt (1≤t≤1041≤t≤104 ) — the number of test cases.
The first line of each test case contains single integer nn (1≤n≤1051≤n≤105 ) — the length of array aa . It is guaranteed that the sum of values of nn over all test cases in the input does not exceed 105105 .
The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (−109≤ai≤109−109≤ai≤109 ).
For each test case, print the minimum number of seconds in which you can make aa nondecreasing.
3 4 1 7 6 5 5 1 2 3 4 5 2 0 -4
2 0 3
大意是给一个序列,第k秒可以给里面的某些数加上2^(k-1),问最少多少秒能使这个数列单调不减。
不妨从序列起始处遍历,设一个变量pre存储当前最大值。当遍历到i位置时,如果a[i]>=pre,说明不用管a[i]了,直接更新pre为a[i]后continue;否则的话求出pre与a[i]的差值,由二进制的性质,这个差值转化为二进制后其最高为1的位就代表使a[i]=pre所用的时间,至于为什么要令a[i]=pre呢?因为贪心地考虑,这样能使之后的数花费的时间尽可能小。举个例子,假设差值为9,9即二进制下的1001,花费4s即可。这样,每个需要增加的数都能求出一个时间,所有时间里取最大即可。
#include <bits/stdc++.h> using namespace std; int n,a[100005]; int get(int num)//得到最高位在哪 { int cnt=0; for(;num;num>>=1) cnt++; return cnt; } int main() { int t; cin>>t; while(t--) { scanf("%d",&n); int i,j; int pre=-2147483647,ans=0;//pre记录的是之前的最高高度 ans记录的是最少时间 for(i=1;i<=n;i++) { scanf("%d",&a[i]); if(a[i]>=pre) { pre=a[i];//别忘记更新 continue; } int diff=pre-a[i],temp=0; int time=get(diff); ans=max(ans,time); } cout<<ans<<endl; } return 0; }