​传送门​

题目大意

给定长度为Codeforces 1081 E_前缀和Codeforces 1081 E_前缀和为偶数)的数列Codeforces 1081 E_差分序列_03的偶数项,求出数列Codeforces 1081 E_差分序列_03的奇数项,使得对于任意Codeforces 1081 E_前缀和_05为平方数,若无解输出Codeforces 1081 E_差分序列_06,否则先输出一行Codeforces 1081 E_前缀和_07,再输出Codeforces 1081 E_前缀和_08,若有多解输出任意一组解。
Codeforces 1081 E_差分序列_03数组奇数项不超过Codeforces 1081 E_差分序列_10,偶数项不超过Codeforces 1081 E_差分序列_11

思路

一边计算一边维护前缀和
差分序列中的一项Codeforces 1081 E_i++_12,必定要满足有Codeforces 1081 E_前缀和_13,即Codeforces 1081 E_前缀和_14,那么现在已知Codeforces 1081 E_i++_12
Codeforces 1081 E_i++_12因式分解,使Codeforces 1081 E_前缀和_17Codeforces 1081 E_i++_12的一对因子。
设其中一个因子为Codeforces 1081 E_差分序列_19,另一个为Codeforces 1081 E_差分序列_20,不妨设Codeforces 1081 E_差分序列_19为一对之中大的那个因子,那么令Codeforces 1081 E_差分序列_22联立两式可解得,Codeforces 1081 E_i++_23。那么Codeforces 1081 E_前缀和_24存在的充分必要条件就是这对因子和(差)为偶数,Codeforces 1081 E_i++_25,Codeforces 1081 E_前缀和_26
针对每个数,我们都选择构造尽量小的平方数,这样保证在之后的构造中能够有更多的选择。在构造当前数的选择上,已经有的前缀和为now,那么当前数就为Codeforces 1081 E_差分序列_27

代码

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]);
}
}