题解:P12642 [KOI 2024 Round 1] 加倍

题目传送门

注意到如果每次都给每个数一直乘二的话,肯定会爆 long long。所以我们要用 \(sum\) 记录前一个乘了几次二,到第 \(i\) 个数时,分讨一下,当前这个数比前一个大还是小,如果大的话就记录要除几次才能比前一个小,假设值为 \(k\),然后答案就加上 \(sum-k+1\),再把 \(sum\) 的值赋值为 \(sum-k+1\)。如果要小的话就相反,计算要乘几次才能大于等于前一个数,答案要加上 \(sum+k\)\(sum\) 赋值为 \(sum+k\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010101;
ll n,a[N],ans,sum,x,k;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		if(i!=1){
			if(a[i]>=a[i-1]){
				x=a[i],k=0;
				while(x/2>=a[i-1]){
					x>>=1;
					k++;
				}
				if(k<sum)ans+=sum-k,sum-=k;
				else sum=0;
			}
			if(a[i]<a[i-1]){
				x=a[i],k=0;
				while(x<a[i-1]){
					x<<=1;
					k++;
				}
				ans+=sum+k;
				sum+=k;
			}
		}
	}
	cout<<ans;
	return 0;
}
posted @ 2025-09-10 21:36  一班的hoko  阅读(8)  评论(0)    收藏  举报