Appearance
Extreme Subtraction -- CF 1443D
Difficulty: 1800 * Techniques: difference array, decomposition into monotone parts, invariant Problem Link
Quick Revisit
- PROBLEM: Can we reduce an array to all zeros using prefix-subtract and suffix-subtract operations?
- KEY INSIGHT: Equivalent to decomposing a = f + g where f is non-increasing and g is non-decreasing. Check: positive diffs sum <= a[0], negative diffs sum <= a[n-1].
- TECHNIQUES: difference array analysis, decomposition into monotone parts
- TRANSFER: "Subtract from prefix/suffix" -- think difference array. Simulation impossible at 10^9 => find algebraic invariant.
First Read
Array of
- Choose
( ), subtract 1 from the first elements. - Choose
( ), subtract 1 from the last elements.
Can we make all elements zero? No constraint on number of operations.
The Simulation Trap
My first instinct: simulate. Maybe greedily subtract from the left or right to equalize? But the order and choice of
OK, I need to think about what operations do structurally, not simulate them.
Reframing as a Decomposition
Stop thinking about the order of operations and look at the totals. Let
Two structural observations:
is non-increasing in : as grows, the set shrinks. is non-decreasing in : as grows, shrinks, so the set grows.
So the question becomes purely combinatorial: can we write
If yes, the corresponding
Why the Difference Array Settles It
Take
To match
: equivalently, , i.e., after using . : equivalently, , i.e., .
The Clean Condition
The array is reducible to zero if and only if
Intuitively: positive jumps in
The Code
cpp
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n; cin >> n;
vector<long long> a(n);
for (auto& x : a) cin >> x;
long long pos = 0, neg = 0;
for (int i = 1; i < n; i++) {
long long d = a[i] - a[i - 1];
if (d > 0) pos += d;
else neg += -d;
}
cout << (pos <= a[0] && neg <= a[n - 1] ? "YES" : "NO") << "\n";
}
int main() {
int t; cin >> t;
while (t--) solve();
}Transfer Lesson
- "Subtract 1 from a prefix/suffix" -- think difference array. These operations have very clean effects on differences.
- Decomposition into monotone parts -- if an array must be expressible as
(non-increasing + non-decreasing), the difference array splits neatly into positive and negative parts. - When simulation is impossible (
values), find an algebraic invariant. The difference array often reveals the right one.
See also: Difference Arrays | Greedy | Invariant Technique | Pattern Recognition Guide | Practice Ladder 1700-2100