题目来源:AtCoder Regular Contest 153的C
https://atcoder.jp/contests/arc153/tasks/arc153_c
题意:给一个数列An,这个数列只包含-1和1,构造一个数列Bn,使得AiBi的总和等于0,如果能构造出来就输出Yes并输出数列Bn,否则就输出No
(构造题,说实话场上是几乎没有看这个题的,就扫了一眼然后发现学校的几个大佬都没过这个题就直接放弃了。占个坑先,也不知道以后会不会用到这个思路了。)
![](https://img-blog.csdnimg.cn/img_convert/c0bdc944ec2c4b8322343867dcc4b6dc.png)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int in() {
int x;
scanf("%d", &x);
return x;
}
const int N = 2e5 + 5;
int n, a[N];
ll b[N];
/* 1 1 1 1 1 -1
-6 -5 -4 -3 -2 -1
-6 -5 -4 16 17 18
-6-5-4-3-2+1=-19
-6-5-4-3+19-2+1=-6-5-4+16-2+1=0
-6-5-4+16=2-1=17-18
一对1 -1,就产生一个-1
一对-1 1,就产生一个1
1 -1 -1 1就会抵消
如果不能抵消,那么就得靠一个数把这个差距给消除掉
*/
int main() {
n = in();
for (int i = 1; i <= n; i++)
a[i] = in();
ll sum = 0;
for (int i = 1; i <= n; i++)
b[i] = i - 1e6, sum += a[i] * b[i];
for (int i = n, s = 0; i >= 1; i--) {
s += a[i];
if ((s == -1 && sum > 0) || (s == 1 && sum < 0)) {
//对称着写
for (int j = i; j <= n; j++)
b[j] += abs(sum);
sum = 0;
break;
}
}
if (sum != 0) {
puts("No");
return 0;
}
puts("Yes");
for (int i = 1; i <= n; i++)
printf("%lld ", b[i]);
puts("");
return 0;
}