C. Powered Addition

You have an array a of length n. For every positive integer xx you are going to perform the following operation during the xx-th second:

  • Select some distinct indices $i_{1}, i_{2}, \ldots, i_{k}$ which are between 1 and n inclusive, and add 2x−12x−1 to each corresponding position of a. Formally, $a_{i_{j}} := a_{i_{j}} + 2^{x-1}$ for j=1,2,…,k. Note that you are allowed to not select any indices at all.

You have to make a nondecreasing as fast as possible. Find the smallest number T such that you can make the array nondecreasing after at most T seconds.

Array a is nondecreasing if and only if $a_{1} \le a_{2} \le \ldots \le a_{n}$.

You have to answer t independent test cases.

对于结果 b[i] , $b[i] >= b[i-1] , b[i] >= a[i] , b[i] = a[i] + \sum 2^S$(S 为数集)

显然要使时间最小,则 $b[i]-a[i]$ 最小。此时,最长时间即 S 的最大值,二进制上即最左边的 1 的位置。

令 $k = a[i] - b[i-1];$ 表示 b[i] 需要 k 即符合条件,k>0 无需处理, 而 k 必然是可以由 x 个 2的次幂相加得到,对于每一位需要的时间即最左边 1 的位置 ,遍历每一位取最大值即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
const int MAX=100000+10;
int t,n,ans,k,le,a[MAX],b[MAX],cnt;
int main(){
//freopen("in","r",stdin);
sf(t);
while(t--){
sf(n);
fi(i,1,n+1) sf(a[i]);
ans = 0;
b[0] = -INF;
fi(i,1,n+1){
k = a[i] - b[i-1];
if(k >= 0) {
b[i] = a[i];
continue;
}else {
k = -k;
b[i] = a[i] + k;
cnt = 0;
while(k){ //求最左边 1 的位置
cnt ++;
if(k&1) {
le = cnt;
}
k>>=1;
}
ans = max(ans,le);
}
}
pfn(ans);
}
return 0;
}