Sum of Three Terms
题意
ARC135B
给出 \(n\) 个数的数列 \(S\),求是否存在长度是 \(n + 2\) 的数列 \(A\), 满足 \(\forall i \in [1, n], S_i = A_i + A_{i + 1} + A_{i + 2}\), \(\forall i \in [1, n + 2], A_i \geq 0\)。
analysis
\[A_{i + 2} = S_i - A_{i + 1} - A_{i}
\]
当给定 \(A_{1}, A{2}\) 时,就能计算出整个数列。
考虑待定系数 \(a = A_{1}, b = A_{2}\)。
带入上面的运算,则有以下性质:
\[\left\{\begin{aligned}
A_i &= x_i + a & (i \equiv 1 \pmod 3) \\
A_i &= x_i + b & (i \equiv 2 \pmod 3) \\
A_i &= x_i - a - b & (i \equiv 0 \pmod 3)
\end{aligned}\right.
\]
其中 \(x\) 是原来的数列 \(A\)。
它们可以转化为不等式组:
\[\left\{\begin{aligned}
a \geq - x_i & (i \equiv 1 \pmod 3) \\
b \geq - x_i & (i \equiv 2 \pmod 3) \\
x_i \leq a + b & (i \equiv 0 \pmod 3)
\end{aligned}\right.
\]
因此解出这个不等式组即可。
令 \(S_1 = \max_{i \equiv 1 \pmod 3} - x_i, S_2 = \max_{i \equiv 2 \pmod 3} - x_i, S_3 = \min_{i \equiv 0 \pmod 3} x_i\)
如果 \(S_1 + S_2 > S_3\) 即无解。
反之,\((A_1, A_2) = (S_1, S_2)\)。
代码
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int MAXN = 300010;
const int INF = 0x7fffffff;
const int mod = 1000000007;
template <typename T>
void Read(T &x) {
x = 0; T f = 1; char a = getchar();
for(; a < '0' || '9' < a; a = getchar()) if (a == '-') f = -f;
for(; '0' <= a && a <= '9'; a = getchar()) x = (x * 10) + (a ^ 48);
x *= f;
}
int n, len;
ll S[MAXN], x[MAXN];
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> S[i];
x[i + 2] = S[i] - x[i + 1] - x[i];
}
ll S1 = -INF, S2 = -INF, S3 = INF;
for (int i = 1; i <= n + 2; i ++) {
if (i % 3 == 1) S1 = max(S1, - x[i]);
if (i % 3 == 2) S2 = max(S2, - x[i]);
if (i % 3 == 0) S3 = min(S3, x[i]);
}
if (S1 + S2 > S3)
return cout << "No", 0;
cout << "Yes" << endl;
ll a = S1, b = S2;
for (int i = 1; i <= n + 2; i ++) {
if (i % 3 == 1) cout << x[i] + a << ' ';
if (i % 3 == 2) cout << x[i] + b << ' ';
if (i % 3 == 0) cout << x[i] - a - b << ' ';
}
return 0;
}