Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
Don’t try to think of the children as being freely reorderable. The line order stays, and every move only touches the first two currently alive children.
At any moment, there is a special child at the front. You can either remove that child as +a_i, or keep them there and remove the next child as -a_j.
Pick the one child who remains unassigned. Once that child becomes first in line, they can never be removed, so every child after them must be removed as the second child and contributes negative.
For a fixed remaining position : child is forced to contribute if , every child can be made either positive or negative, and every child after is forced negative.
So for fixed , the best value is . Also handle separately: then the answer is .
The operation looks annoying because the line changes, but the key is that the order never changes. We only delete things.
So the current line is always the original order with some children missing. At each step, Santa can remove either:
The first child acts like a blocker. If you keep them, you can repeatedly delete the next child as the second child. If you finally remove the blocker, the next surviving child becomes the new blocker.
That is basically the whole game. No dark magic, no cursed DP table.
Fix the remaining child
Suppose child is the one left unassigned at the end.
First, consider every child after .
Once child becomes the first child in line, we cannot remove them, because they are supposed to remain. The only way to keep going is to remove the child after them as the second child. Then the next child after that is second, and so on.
Therefore every child is forced to be removed as the second child, contributing:
So the suffix after contributes:
Now look before .
Child is special. Initially, there is no child before child , so child can never be removed as the second child. It has only two possibilities:
For the middle children , we have freedom. Each such child can be made either:
So for each , we simply choose the better of and , which is:
This is the part where a fake complicated DP gets absolutely bodied by just understanding the process.
Value for a fixed remaining position
If , child remains, and every other child is removed as second:
If , then:
So:
The answer is:
Why the freedom before is real
Take any child with .
If we want child to be negative, keep the current first child alive and remove as the second child.
If we want child to be positive, first remove the current first child. Then child becomes the first child, and later we remove it as first.
This lets us choose the sign of every middle child independently. The only exception is child , because nothing can stand before it.
Implementation
Precompute suffix sums:
Then:
For each :
Update the answer, then add to prefAbs for the next position.
Use long long, because values can reach around , and int would explode like it got reviewed by a compiler with trust issues.
Complexity: per test case, and memory. You can also do it with less memory, but suffix sums are clean and boring, which is exactly what we want here.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<ll> a(n + 2), suf(n + 3, 0);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i >= 1; i--) {
suf[i] = suf[i + 1] + a[i];
}
ll ans = -suf[2]; // Leave child 1 unassigned.
ll prefAbs = 0;
for (int r = 2; r <= n; r++) {
ans = max(ans, a[1] + prefAbs - suf[r + 1]);
prefAbs += llabs(a[r]);
}
cout << ans << '\n';
}
return 0;
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<ll> a(n + 2), suf(n + 3, 0);
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i >= 1; i--) {
suf[i] = suf[i + 1] + a[i];
}
ll ans = -suf[2]; // Leave child 1 unassigned.
ll prefAbs = 0;
for (int r = 2; r <= n; r++) {
ans = max(ans, a[1] + prefAbs - suf[r + 1]);
prefAbs += llabs(a[r]);
}
cout << ans << '\n';
}
return 0;
}