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.
Ignore the actual magnitudes for a second. Track only the sign pattern as bits: if positive, if negative. What does one operation do to that bitmask?
Use position as the least significant bit. An operation at is allowed exactly when bit is , and then it toggles bits .
That operation always makes the binary number smaller. So every reachable final sign mask satisfies , where is the initial positive-mask.
Now maximize weighted set bits among masks . If , let be the highest differing bit. Then , , higher bits are fixed, and lower bits should all be because every is positive.
Try every positive position : keep positions above unchanged, make negative, and make all positions below positive. Its score is . To realize it, first make prefix all negative, then flip .
Let
So bit tells whether is currently positive. If we perform operation , bit must be , and bits are toggled:
Look at the lower bits as a number . Since bit is set,
After toggling those bits, the new lower part is
Higher bits do not change, so the whole mask strictly decreases. That is the key: every valid final mask must satisfy
No vibes, no magic, just binary being annoyingly useful.
For a final mask , the final sum is
The first term is constant, so we only need to maximize
among all .
If , the score is simply the weight of initially positive elements.
Otherwise, let be the highest bit where and differ. Since , we must have
and all bits above are equal to . Bits below are completely free from the numeric constraint, and every weight is positive, so the best choice is to set all of them to .
Therefore, every optimal candidate is one of these:
or for some positive position :
The score for choosing is
Compute prefix sums of and suffix sums of initially-positive , then try all with .
If the best choice is , output no operations.
Otherwise, suppose the chosen position is . We need the final state to have:
The final operation will be . Since is initially positive and operations below never touch it, that operation will be valid.
Before flipping , we want positions to all be negative, because operation will flip them all to positive.
To make prefix all negative, scan downward from to . Maintain a parity telling whether previous larger operations have toggled the current bit. If the current bit is positive, operate there; this makes it negative and toggles all lower bits.
This uses at most one operation per index, plus the final operation at , so
Every operation strictly decreases the sign mask , so no valid sequence can end at a mask greater than the initial one. Thus any achievable final answer is bounded by the best weighted mask .
The optimization step checks exactly the only masks that can be optimal under : either , or at the highest differing bit , we turn that bit off and set every lower bit on.
The construction produces exactly the selected mask: first it makes all bits below equal to , then operation flips them to and flips bit to , while leaving all higher bits unchanged. Every operation is performed only when its current bit is , so the sequence is valid.
Therefore the produced sequence maximizes the final sum.
For each test case, everything is linear:
time and
memory. Across all test cases this is .
#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), w(n + 1), pref(n + 1), suffPos(n + 2);
vector<int> pos(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
w[i] = (a[i] < 0 ? -a[i] : a[i]);
pos[i] = (a[i] > 0);
pref[i] = pref[i - 1] + w[i];
}
for (int i = n; i >= 1; i--) {
suffPos[i] = suffPos[i + 1] + (pos[i] ? w[i] : 0);
}
ll best = suffPos[1];
int bestP = 0;
for (int p = 1; p <= n; p++) {
if (!pos[p]) continue;
ll cand = pref[p - 1] + suffPos[p + 1];
if (cand > best) {
best = cand;
bestP = p;
}
}
vector<int> ops;
if (bestP != 0) {
int flip = 0;
for (int i = bestP - 1; i >= 1; i--) {
int cur = pos[i] ^ flip;
if (cur) {
ops.push_back(i);
flip ^= 1;
}
}
ops.push_back(bestP);
}
cout << ops.size() << '\n';
for (int i = 0; i < (int)ops.size(); i++) {
if (i) cout << ' ';
cout << ops[i];
}
cout << '\n';
}
}#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), w(n + 1), pref(n + 1), suffPos(n + 2);
vector<int> pos(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
w[i] = (a[i] < 0 ? -a[i] : a[i]);
pos[i] = (a[i] > 0);
pref[i] = pref[i - 1] + w[i];
}
for (int i = n; i >= 1; i--) {
suffPos[i] = suffPos[i + 1] + (pos[i] ? w[i] : 0);
}
ll best = suffPos[1];
int bestP = 0;
for (int p = 1; p <= n; p++) {
if (!pos[p]) continue;
ll cand = pref[p - 1] + suffPos[p + 1];
if (cand > best) {
best = cand;
bestP = p;
}
}
vector<int> ops;
if (bestP != 0) {
int flip = 0;
for (int i = bestP - 1; i >= 1; i--) {
int cur = pos[i] ^ flip;
if (cur) {
ops.push_back(i);
flip ^= 1;
}
}
ops.push_back(bestP);
}
cout << ops.size() << '\n';
for (int i = 0; i < (int)ops.size(); i++) {
if (i) cout << ' ';
cout << ops[i];
}
cout << '\n';
}
}