C - Sum = 0
解説
条件を満たすような数列 が存在する必要十分条件は、
であること。この条件を満たすとき、数列 は次のように構成できる。
- で初期化する
- と置く
- 各 に対して次の操作を行う。
- と置く
- で更新する
- で更新する
つまり、最初に で初期化し、総和が になるように各 を小さくしていく。各 を小さくできる限界は であるため、 と の小さい方を引くことで、 を更新する。
で初期化し、総和が になるように各 を大きくしていくこともできる。その場合は、 で更新していく。
提出コード
- Go
func main() {
n := readInt()
L := make([]int, n)
R := make([]int, n)
for i := 0; i < n; i++ {
var l, r int
scanIntVariables(&l, &r)
L[i] = l
R[i] = r
}
mi := sum(L...)
ma := sum(R...)
if mi > 0 || ma < 0 {
writeLine("No")
return
}
writeLine("Yes")
Ans := make([]int, n)
for i := 0; i < n; i++ {
Ans[i] = R[i]
t := min(R[i]-L[i], ma)
Ans[i] -= t
ma -= t
}
for i := 0; i < n; i++ {
write(Ans[i], " ")
}
writeLine()
}
- C++
int main() {
int n; cin >> n;
vector<ll> L(n), R(n); rep(i, 0, n) cin >> L[i] >> R[i];
ll mi = 0, ma = 0;
rep(i, 0, n) {
mi += L[i];
ma += R[i];
}
if (mi >0 || ma < 0) {
cout << "No" << endl;
return 0;
}
vector<ll> Ans(n);
rep(i,0,n) {
Ans[i] = R[i];
ll t = min(R[i]-L[i],ma);
Ans[i] -= t;
ma -= t;
}
cout << "Yes" << endl;
rep(i,0,n) cout << Ans[i] << " "; cout << endl;
}