本文章由 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
*\/

鲁ICP备2025150228号