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.
Write the current alternating sum as . The cost part is always added positively, so the only tricky part is how a swap changes .
Swapping two indices with the same parity does not change the alternating sum, because both positions have the same sign. It only adds positive cost, so a player who wants to maximize would love it, and the minimizer hates it.
Because either player may end the game on their own turn, Bob can always stop immediately after Alice's first swap. That means Alice only needs to consider what value she can force with one move, then Bob says “nah” and ends if continuing is bad for him.
Alice can also exploit a same-parity swap: it keeps unchanged and adds distance. The best same-parity distance is if is odd, otherwise .
For an odd/even swap , with odd and even, the final value changes by . With even and odd, it changes by . Scan left to right while keeping the best previous expression for the opposite parity.
Let
That is the value of the array before any swaps, ignoring cost.
The important game observation is brutal but simple: the game ends after at most Alice's first meaningful move under optimal play.
Why? Alice moves first. If she ends immediately, the answer is . If she swaps something, then Bob gets the next turn and can end the game immediately. Since Bob minimizes the final value, Alice cannot rely on Bob generously making extra moves that help her. So Alice's job is just:
The rest is figuring out that best gain.
Effect of a swap
Let the sign at index be:
Before swapping indices , their contribution is
After swapping, it becomes
So the change in alternating sum is
The swap also adds cost .
We only consider , so the cost is .
Same parity swaps
If and have the same parity, then . Swapping them does not change at all. The gain is just:
Alice wants the largest distance between two indices of the same parity.
For , this is .
So initialize:
Different parity swaps
Now suppose and the parities differ.
Case 1: odd, even.
Before:
After:
Change in alternating sum:
Including cost, gain is:
or equivalently:
So while scanning left to right, for an even index , we want the maximum previous odd value of:
Case 2: even, odd.
Before:
After:
Change in alternating sum:
Including cost, gain is:
or:
So for an odd index , we want the maximum previous even value of:
That gives an scan:
bestOdd = max(-i - 2*a[i]) over previous odd indices.bestEven = max(-i + 2*a[i]) over previous even indices.Take the maximum of these and the same-parity gain.
Finally print:
The values fit in long long: is at most about in magnitude, and gains are also around that size. int would explode. Not dramatically, just enough to ruin your day.
#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 + 1);
ll base = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i & 1) base += a[i];
else base -= a[i];
}
ll best = 0;
if (n >= 2) best = (n & 1) ? n - 1 : n - 2;
const ll NEG = -(1LL << 60);
ll bestOdd = NEG; // max over odd i: -i - 2*a[i]
ll bestEven = NEG; // max over even i: -i + 2*a[i]
for (int j = 1; j <= n; j++) {
if (j & 1) {
if (bestEven != NEG) {
best = max(best, (ll)j - 2 * a[j] + bestEven);
}
bestOdd = max(bestOdd, -(ll)j - 2 * a[j]);
} else {
if (bestOdd != NEG) {
best = max(best, (ll)j + 2 * a[j] + bestOdd);
}
bestEven = max(bestEven, -(ll)j + 2 * a[j]);
}
}
cout << base + best << '\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 + 1);
ll base = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i & 1) base += a[i];
else base -= a[i];
}
ll best = 0;
if (n >= 2) best = (n & 1) ? n - 1 : n - 2;
const ll NEG = -(1LL << 60);
ll bestOdd = NEG; // max over odd i: -i - 2*a[i]
ll bestEven = NEG; // max over even i: -i + 2*a[i]
for (int j = 1; j <= n; j++) {
if (j & 1) {
if (bestEven != NEG) {
best = max(best, (ll)j - 2 * a[j] + bestEven);
}
bestOdd = max(bestOdd, -(ll)j - 2 * a[j]);
} else {
if (bestOdd != NEG) {
best = max(best, (ll)j + 2 * a[j] + bestOdd);
}
bestEven = max(bestEven, -(ll)j + 2 * a[j]);
}
}
cout << base + best << '\n';
}
return 0;
}