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.
The maximum subarray sum is monotone: increasing any can never make the answer worse, and decreasing any can never make it better. So Alice only really wants Add, and Bob only really wants Subtract.
The order of changes does not matter for the final array. Think of Alice's moves as adding some multiset of values, and Bob's moves as removing some multiset of values.
Bob can always cancel Alice's move by playing the same index with the opposite operation. So when is even, Bob can cancel every Alice move. When is odd, Bob can cancel all but one Alice move.
For the lower bound, Alice should not chase the whole array. Pick a target subarray , pick the index with maximum , and keep adding at . Bob has no better inside- subtraction than losing at most per move.
Therefore: if is even, the answer is just the normal max subarray sum of . If is odd, the answer is : one uncanceled Alice bonus inside the chosen subarray.
The annoying part of the game is that it looks like turns matter. They basically don't. Only the parity matters. Classic Codeforces behavior: huge , tiny idea.
Let be the maximum non-empty subarray sum of array .
First, notice a simple monotonicity fact:
So Alice never needs to subtract, and Bob never needs to add. Operations also commute, because only the final array matters.
Even number of turns
Suppose . Alice makes moves and Bob makes moves.
Bob has an easy upper-bound strategy: after every Alice move at index , Bob plays the opposite move at the same index. After every pair of moves, the array is back where it started. So Bob can guarantee the final score is at most
Now we need to show Alice can guarantee at least , otherwise Bob might do even better.
Take a maximum-sum subarray of the original array . Let be an index in with maximum among all indices in .
Alice plays index every time. Bob has moves. Any Bob move outside does not affect the sum of . Any Bob move inside subtracts at most , because was the maximum inside .
Alice adds to , while Bob can remove at most from . Therefore the final sum of is at least its original sum, which is .
So for even :
Odd number of turns
Now suppose . Alice has one extra move.
Bob can cancel Alice's first moves. After that, Alice gets exactly one uncanceled move. So the final array is no better for Alice than taking the original array and adding to one chosen index .
If the final maximum subarray is , and Alice's uncanceled bonus lies inside , its value is
for some . Alice would choose the best possible , so for a fixed the best bonus is .
Thus Bob can hold Alice to at most
Again, prove Alice can actually guarantee this.
Pick a subarray that attains , and let be an index in with maximum . Alice plays index on every one of her turns.
Bob has only moves. Inside , each Bob subtraction removes at most . Therefore the final sum of is at least
So for odd :
Important trap: this is not Kadane on . That would add every in a subarray, which is illegal. Alice only has one uncanceled bonus, not a coupon for the whole damn segment.
Computing the odd case
Scan left to right with two DP states:
For index :
For , there are three choices:
So:
The odd answer is the maximum seen.
The even answer is just standard Kadane on .
Complexity is per test case and extra memory besides the input arrays. The total is , so this is easily fine.
#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;
const ll NEG = -(1LL << 62);
while (t--) {
int n;
ll k;
cin >> n >> k;
vector<ll> a(n), b(n);
for (ll &x : a) cin >> x;
for (ll &x : b) cin >> x;
if (k % 2 == 0) {
ll cur = 0, ans = NEG;
for (ll x : a) {
cur = max(x, cur + x);
ans = max(ans, cur);
}
cout << ans << '\n';
} else {
ll dp0 = NEG, dp1 = NEG, ans = NEG;
for (int i = 0; i < n; i++) {
ll ndp1 = max({a[i] + b[i], dp0 + a[i] + b[i], dp1 + a[i]});
ll ndp0 = max(a[i], dp0 + a[i]);
dp0 = ndp0;
dp1 = ndp1;
ans = max(ans, dp1);
}
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;
const ll NEG = -(1LL << 62);
while (t--) {
int n;
ll k;
cin >> n >> k;
vector<ll> a(n), b(n);
for (ll &x : a) cin >> x;
for (ll &x : b) cin >> x;
if (k % 2 == 0) {
ll cur = 0, ans = NEG;
for (ll x : a) {
cur = max(x, cur + x);
ans = max(ans, cur);
}
cout << ans << '\n';
} else {
ll dp0 = NEG, dp1 = NEG, ans = NEG;
for (int i = 0; i < n; i++) {
ll ndp1 = max({a[i] + b[i], dp0 + a[i] + b[i], dp1 + a[i]});
ll ndp0 = max(a[i], dp0 + a[i]);
dp0 = ndp0;
dp1 = ndp1;
ans = max(ans, dp1);
}
cout << ans << '\n';
}
}
return 0;
}