明明是一道简单题,却因为mx初始值没有设置成负无穷而直接写了个0花了一个小时,后面的也没时间写了,害
题面
题意
给定一个长度为 n 的数组
在第 k 秒钟时,可以往数组的任意元素上加上 2^k-1^,随便选,也可以不选
问最少需要多少秒的时间,才能让这个数组变成不递减的数列
解题思路
因为只能往元素上加正值
所以某个位置 x 必须进行改变的条件就是在 1 ~ x-1 之中存在一个值比位置 x 的值要大,导致出现了递减
则位置 x 的值必须改变成大于等于前面最大值的数
从二进制的角度看待这个问题的话可以发现
如果某个位置的数至少要加上 d 才能与前面的最大值相同
将d转成二进制后,d的最高位所在的位数就是完成这一步骤需要的总时间
而从低位到高位的0和1则代表着在那一秒钟是否需要让它进行改变
因此,最优解就是找出所有的逆序对,逆序对中差值最大的那个差值的最高位所在位数就是答案
程序
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
void solve()
{
int n,ans=0,ar,mx=-INF,mxd=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>ar;
mx=max(mx,ar);
mxd=max(mxd,mx-ar);
}
while(mxd)
{
mxd>>=1;
ans++;
}
cout<<ans<<'
';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
for(int t=1;t<=T;t++)
solve();
return 0;
}