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.
Try looking from the right end. A prefix flip at index never touches positions . That smells like finalizing elements one by one.
The best possible sum cannot be smaller than
because each value keeps its absolute value forever. So the whole game is: can we make every element negative?
Suppose you are fixing position , and all positions are already negative. If , do nothing. If , operation is legal and flips it to negative.
After operating at index , only positions change. So whatever you already fixed to the right stays fixed. This is the whole greedy proof; no hidden DP monster under the bed.
Algorithm: scan . Maintain whether previous flips have inverted the current sign. Whenever current is positive, append operation and toggle that flip state. This makes every element negative, reaching , which is obviously optimal.
The absolute values never change. Only signs flip. Therefore every final array has sum at least
because each term is either or . So if we can make every number negative, we are done. That is the best possible sum, full stop.
Operation flips exactly the prefix .
That means operation does not touch positions . So we can safely finalize the array from right to left.
When we are at position :
After this, future operations only use smaller indices, so position will never be touched again.
Naively flipping prefixes would be , which is dumb and deserves jail time.
Instead, keep one parity variable :
For original value , its current positivity is:
If it is currently positive, append to the answer and toggle .
Why does toggling one variable work? While scanning right to left, every operation we have already performed was on an index larger than the current one, so it flipped the current position. Every future position also lies inside the prefix we just flipped.
We prove the invariant: after processing position , every position is negative and will never change again.
Before processing anything, the claim is vacuously true for positions to the right of .
Now consider position .
If is currently negative, we do nothing, so it is finalized as negative.
If is currently positive, operation is allowed by the statement. It flips , making it negative. It may flip positions , but those are not finalized yet. It does not affect positions , so previously finalized positions remain negative.
Thus the invariant holds.
At the end, all positions are negative, so the final sum is
which is the smallest possible sum. Therefore the produced sequence is optimal.
We scan the array once and output at most one operation per index.
#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);
for (int i = 1; i <= n; i++) cin >> a[i];
vector<int> ops;
bool flipped = false;
for (int i = n; i >= 1; i--) {
bool positive_now = (a[i] > 0) ^ flipped;
if (positive_now) {
ops.push_back(i);
flipped = !flipped;
}
}
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);
for (int i = 1; i <= n; i++) cin >> a[i];
vector<int> ops;
bool flipped = false;
for (int i = n; i >= 1; i--) {
bool positive_now = (a[i] > 0) ^ flipped;
if (positive_now) {
ops.push_back(i);
flipped = !flipped;
}
}
cout << ops.size() << '\n';
for (int i = 0; i < (int)ops.size(); i++) {
if (i) cout << ' ';
cout << ops[i];
}
cout << '\n';
}
}