Codeforces 1081 E
原创
©著作权归作者所有:来自51CTO博客作者mb62d0cd6d0f38c的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目大意
给定长度为(为偶数)的数列的偶数项,求出数列的奇数项,使得对于任意为平方数,若无解输出,否则先输出一行,再输出,若有多解输出任意一组解。
数组奇数项不超过,偶数项不超过。
思路
一边计算一边维护前缀和
差分序列中的一项,必定要满足有,即,那么现在已知
把因式分解,使为的一对因子。
设其中一个因子为,另一个为,不妨设为一对之中大的那个因子,那么令联立两式可解得,。那么存在的充分必要条件就是这对因子和(差)为偶数,,。
针对每个数,我们都选择构造尽量小的平方数,这样保证在之后的构造中能够有更多的选择。在构造当前数的选择上,已经有的前缀和为now,那么当前数就为。
代码
int n;
int q=0;
ll a[maxn],b[maxn];
ll now;
int main(){
scanf("%d",&n);
for(int i=1;i<=n/2;i++){
scanf("%lld",&a[i]);
}
for(int i=1;i<=n/2;i++){
ll tmp,ans=1e15;
for(int j=1;j*j<=a[i];j++){
if(a[i]%j) continue;
ll xx=j,yy=a[i]/j;
if((xx-yy)%2)continue;
tmp=(xx-yy)*(xx-yy)/4;
if(tmp>now)ans=min(ans,tmp);
}
if(ans==1e15){
puts("No");
return 0;
}
b[++q]=ans-now;
b[++q]=a[i];
now=a[i]+ans;
}
puts("Yes");
for(int i=1;i<=n;i++){
printf("%lld ",b[i]);
}
}