題意
給一個序列 ,可以在第 秒給任意位置的多個元素加上 ,問把 變成一個不下降的序列,最少要多少秒?
思路
既然是要把序列變成一個不下降的序列的最少時間,肯定是把互爲逆序對並且差值最大的兩個數給補成不下降狀態所需的時間(因爲可以任意選取數,所以在把最大差的逆序對補齊的時候,其他的都可以在這個過程中完成)。
確定時間的話,只要把到第 秒的可加數和 與 差值比較一下即可,當可加數和 第一次大於等於差值,即是答案。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5+7;
int n,m,cas;
ll b[N],a[100],s[100];
//求 i時刻 的可加數和
void init(){
a[1] = 1;
s[1] = 1;
for(int i = 2; i <= 32; ++i){
a[i] = a[i-1]*2;
s[i] = a[i]+s[i-1];
}
}
int main(){
init();
scanf("%d",&cas);
while(cas--){
int ans = 0;
scanf("%d",&n);
for(int i = 1;i <= n; ++i)
scanf("%lld",b+i);
ll maxx = b[1],sub=0;
for(int i = 2; i <= n; ++i){
maxx = max(maxx,b[i]);//maxx爲b[1]~b[i]的最大值
sub = max(sub,maxx-b[i]);//sub爲b[1]~b[i]的最大差值
for(int j = 0; j <= 33; ++j)
if(sub <= s[j]){
ans = max(ans,j);//找到b[1]~b[i]中補齊最大差值所需的時間,並取一個最大值
break;
}
}
printf("%d\n",ans);
}
return 0;
}