Codeforces 1338A/1339C


明明是一道简单题,却因为mx初始值没有设置成负无穷而直接写了个0花了一个小时,后面的也没时间写了,害


题面

1339C




题意

给定一个长度为 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;
}

原文地址:https://www.cnblogs.com/stelayuri/p/12689098.html