题解: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;
}

浙公网安备 33010602011771号