Powered Addition(思維+貪心+位運算)Codeforces Round #633 (Div. 2)

在這裏插入圖片描述

題目大意

       給出一個長度爲n(n<=100000)n(n<=100000)的數組,在第ii秒時可以任意選出一些數使它們的值增加2i12^{i-1},問如果要使得該數組不遞減至少需要多少秒?

分析過程

       (感覺這道題挺妙的…… )我們經過分析可以發現,如果從左到右遍歷數組,對於數組中碰到的第一組滿足a[i]>a[i+1]a[i]>a[i+1]的兩個相鄰元素,我們必然要增加a[i+1]a[i+1]來消除這個逆序,我們的最優貪心策略必然是使得a[i+1]a[i+1]增加到與a[i]a[i]相等,這樣可以保證用的時間是最少的。這個時候,如果對於二進制位運算比較敏感的話,很容易察覺到,所用的時間就是high_bit(x)high\_ bit(x),其中,x=a[i]a[i+1]x=a[i]-a[i+1]high_bit(x)high\_ bit(x)表示xx對應的二進制位的最高位置(一個策略對應於一個二進制表示,以二進制位置表示時間,1或0表示是否疊加對應值。)。
       現在,我們一般化這個思路,在使得a[i+1]==a[i]a[i+1]==a[i]之後,如果後面的值大於等於這個值那就自然滿足不遞減,這個時候我們就更新一下最大值(因爲後面的值應該比左側過來的最大值大),如果小於的話,我們更新一下答案,即ans=max(ans,high_bit(maxia[i]))ans=max(ans, high\_ bit(maxi-a[i]))

AC代碼

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 100;
typedef long long ll;
ll n, a[maxn], c[maxn];
ll high_bit(ll x){
	ll i = 63, e = 1;
	while(!(x & (e << i))) --i;
	return i + 1; 
}
void solve(){
	ll i, x, maxi = -10000000000, ans = 0;
	for(i=1;i<=n;++i){
		if(a[i] >= maxi) maxi = a[i];
		else{
			ll temp = high_bit(maxi - a[i]);
			ans = max(ans, temp);
		}
	}
	cout<<ans<<'\n';
}
int main(){
	int t, i, j;
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--){
		cin>>n;
		for(i=1;i<=n;++i) cin>>a[i];
		solve();
	}
	return 0;
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章