Codeforces 1081 E

传送门

题目大意

给定长度为 n n n n n n为偶数)的数列 x x x的偶数项,求出数列 x x x的奇数项,使得对于任意 t ∈ [ 1 , n ] , x 1 + x 2 + . . . + x t t∈[1,n],x1+x2+...+xt t[1,n]x1+x2+...+xt为平方数,若无解输出 N o No No,否则先输出一行 Y e s Yes Yes,再输出 x 1 , x 2 , x 3 , . . . , x n x1,x2,x3,...,xn x1,x2,x3,...,xn,若有多解输出任意一组解。
x x x数组奇数项不超过 1 0 13 10^{13} 1013,偶数项不超过 1 0 5 10^5 105

思路

一边计算一边维护前缀和
差分序列中的一项 c c c,必定要满足有 a 2 − b 2 = c a^2−b^2=c a2b2=c,即 ( a − b ) × ( a + b ) = c (a−b)×(a+b)=c (ab)×(a+b)=c,那么现在已知 c c c
c c c因式分解,使 ( a − b ) , ( a + b ) (a−b),(a+b) (ab),(a+b) c c c的一对因子。
设其中一个因子为 x x xx xx,另一个为 y y yy yy,不妨设 x x xx xx为一对之中大的那个因子,那么令 a + b = x x , a − b = c / x x a+b=xx,a−b=c/xx a+b=xx,ab=c/xx联立两式可解得, 2 a = x x + c / x x , 2 b = x x − c / x x 2a=xx+c/xx,2b=xx−c/xx 2a=xx+c/xx,2b=xxc/xx。那么 a , b a,b ab存在的充分必要条件就是这对因子和(差)为偶数, n < = 1 0 5 n<=10^5 n<=105, b 2 = ( x x − y y ) ∗ ( x x − y y ) / 4 b^2=(xx-yy)*(xx-yy)/4 b2=(xxyy)(xxyy)/4
针对每个数,我们都选择构造尽量小的平方数,这样保证在之后的构造中能够有更多的选择。在构造当前数的选择上,已经有的前缀和为now,那么当前数就为 a n s − n o w ans−now ansnow

代码

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]);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值