题意
给定序列 \(a\),每次操作可以使 \(a_i\gets a_i^2\),求使 \(a\) 不降的最少操作次数。
分析
因为 \(1^k=1\),所以无解的情况只有 \(\exist\ a_i=1\) 且 \(\exist\ j\in[1,i), a_j>1\)。
在有解的情况下,假设对 \(a_{i-1}\) 操作 \({k_{i-1}}\) 次,对 \(a_i\) 操作 \({k_i}\) 次。
此时 \(a_{i-1}\gets a_{i-1}^{2^{k_{i-1}}}\),\(a_i\gets a_i^{2^{k_i}}\)。
因为单调不降,且序列中所有元素均为正数,所以满足:
\[\begin{aligned} a_{i-1}^{2^{k_{i-1}}} &\leq a_i^{2^{k_i}} \\ \log_2a_{i-1}^{2^{k_{i-1}}} & \leq \log_2a_i^{2^{k_i}} \\ 2^{k_{i-1}}\log_2 a_{i-1} & \leq 2^{k_i}\log_2 a_i \\ \log_2(2^{k_{i-1}}\log_2 a_{i-1}) & \leq \log_2(2^{k_i}\log_2 a_i) \\ {k_{i-1}}+\log_2 \log_2 a_{i-1} & \leq {k_i}+\log_2 \log_2 a_i \\ {k_{i-1}}+\log_2\log_2a_{i-1}-\log_2\log_2a_i & \leq {k_i} \\ \end{aligned} \]所以 \({k_i}\) 的最小取值为 \(\lceil {k_{i-1}}+\log_2\log_2a_{i-1}-\log_2\log_2a_i \rceil\)。
注意 \({k_i}\) 不能取负数,所以 \({k_i} \gets \max({k_i}, 0)\)。
显然第一位不操作,故 \(k_1=0\)。
逐项处理即可。
答案就是 \(\sum k_i\)。
Code
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define eps 1e-8
int a[maxn];
void solve()
{
int64_t n, ans=0;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int la=0;
for(int i=2;i<=n;i++)
{
if(a[i]==1&&a[i-1]!=1) return cout<<-1<<'\n', void();
la=max((int)ceil(la+log2(log2(a[i-1]))-log2(log2(a[i]))-eps), 0);
ans+=la;
}
cout<<ans<<'\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int t;
cin>>t;
while(t--) solve();
}
标签:log,int,题解,Squaring,leq,2a,CF1995C,操作,gets
From: https://www.cnblogs.com/redacted-area/p/18379559