Logo S08577 的博客

博客

CF1883E

...
S08577
2025-12-01 12:57:31

本文章由 WyOJ Shojo 从洛谷专栏拉取,原发布时间为 2024-09-07 14:12:43

思路

首先,贪心不难发现 $a$ 数组的值改动的越少越好。

不难想到暴力,将 $a_i \times 2$ 直到 $a_i > a_{i-1}$,但是复杂度不允许。

不妨优化,利用前缀和思想:如果后面的数比当前小,则一定会有重复的步骤在当前的数已经计算过。

运用前缀和的前提: $$\forall a_i \Rightarrow \frac{a_i \times 2^x}{a_{i-1} \times 2^x}=\frac{a_i}{a_{i-1}}$$

令 $t_i$ 为 $a_i$ 需要乘二的次数。

则 $t_i$ 为 $a_i$ 与 $a_{i-1}$ 需要乘二的个数加上 $t_{i-1}$。

结果为 $\sum ^n_ {i=1} t_i$。

注意一点,如果 $t_i<0$,则 $t_i=0$ 。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<set>


using namespace std;

#define int long long
#define ll long long
#define Endl cout<<endl;
#define ENdl Endl
#define xy cout<<"xy";
#define yx cout<<"yx";
#define pii pair<int,int>
#define lowbit(x) x&(-x)
#define fi first
#define se second
#define fst ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

const int N=5e6+10;\/\/注意修改
const int mod=1e9+7;
const int Max=0x3f3f3f3f3f;

int a[N];

void solve(){
    int n;
    cin>>n;
    int cnt=0,sum=0,ans=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++){
        cnt=0;
        int l=a[i-1],r=a[i];
        \/\/if(l<=r) continue;
        while(l<r) l*=2,cnt--;\/\/少乘
        while(l>r) r*=2,cnt++;\/\/多乘
        sum+=cnt;\/\/最后乘多少
        if(sum<0) sum=0;\/\/如果是负数,那就不用管
        ans+=sum;
    }

    cout<<ans<<endl;

}


\/*
 *\/
signed main(){
    
\/\/   freopen("a.in","r",stdin);
\/\/   freopen("a.out","w",stdout);
    int T;
    cin>>T;
    while(T--){
        solve();
    }
    return 0;
}



\/*
 1
 5 3
 2 4 5

 *\/

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。