zoukankan      html  css  js  c++  java
  • 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 2x12x−1 to each corresponding position of aa . Formally, aij:=aij+2x1aij:=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 a1a2ana1≤a2≤…≤an .

    You have to answer tt independent test cases.

    Input

    The first line contains a single integer tt (1t1041≤t≤104 ) — the number of test cases.

    The first line of each test case contains single integer nn (1n1051≤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 (109ai109−109≤ai≤109 ).

    Output

    For each test case, print the minimum number of seconds in which you can make aa nondecreasing.

    Example
    Input
    Copy
    3
    4
    1 7 6 5
    5
    1 2 3 4 5
    2
    0 -4
    
    Output
    Copy
    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;
     } 
                
  • 相关阅读:
    Iterator接口源码阅读
    Iterator接口实现类
    Enumeration接口源码阅读
    lambda表达式
    方法引用
    JAVA并发之AQS概述
    牛牛取快递——从dfs到dijkstra以及堆优化的dijkstra
    牛客2018java模拟编程题
    排序算法java实现以及简易性能测试
    java 死锁例子以及闭锁使用确保死锁产生
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/12690046.html
Copyright © 2011-2022 走看看