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.
One valid operation removes some left sum and some right sum . So before worrying about construction, ask what this forces about the total amount removed.
Every operation removes an even total, so must be even. Also, in one operation no single position can remove more than half of that operation's total; summing over operations gives for every .
A one-move solution is brutally constrained: if everything becomes zero in one move, then the chosen array must be exactly . So one move works iff some prefix sum is .
If no prefix is exactly , take the first index where the running sum crosses . Compress the whole array into three chunks: left sum , pivot value , and right sum .
Let . Put from the pivot and total from the right suffix into the second operation. Everything else goes into the first operation; the hidden split points are before and after the pivot.
The bound of 17 is doing a little stage magic here: the real answer is only , , or .
Suppose an operation uses array and split point . Then
So this operation removes total , always even.
Also, for any fixed position , the removed amount lies on one side of the split, whose total is . Therefore , which means is at most half of this operation's removed total.
Now sum that inequality over all operations. If the initial total is , position removes exactly overall, while all operations together remove overall. So we must have
If either condition fails, print . This is not just a vibe check; it is forced.
If we finish in one operation, then the selected array must be , because every element has to be fully subtracted immediately. That is valid exactly when there is some split point with prefix sum .
So after computing prefix sums:
1 and the original array;Let . Since no prefix equals , find the first index such that the prefix sum through is greater than .
Write the array as three parts:
By definition of ,
Set
So , and because , we have , meaning the pivot has enough value to contribute to the second operation.
We also need the right side to contribute total . This is where the max-element condition matters. Since ,
So the right suffix has enough total value. Choose any amounts from positions after with and . Greedily taking from the end is fine.
Now define the second operation:
This operation is valid by splitting right after : the prefix side has sum , and the suffix side also has sum .
Define the first operation as everything not used in the second operation:
Check its split right before . The left side has sum . The right side has
So the first operation is valid too.
After the first operation, the remaining array is exactly , and the second operation deletes it. Done.
The algorithm is linear: compute sum/max/prefixes, then maybe greedily carve from the suffix. Total complexity is per test case.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
void printVec(const vector<ll>& v) {
for (int i = 0; i < (int)v.size(); i++) {
cout << v[i] << (i + 1 == (int)v.size() ? '\n' : ' ');
}
}
void solve() {
int n;
cin >> n;
vector<ll> a(n);
ll sum = 0, mx = 0;
for (ll &x : a) {
cin >> x;
sum += x;
mx = max(mx, x);
}
if (sum % 2 || mx * 2 > sum) {
cout << -1 << '\n';
return;
}
ll half = sum / 2;
ll pref = 0;
int p = 0;
while (p < n && pref + a[p] < half) {
pref += a[p];
p++;
}
if (p < n && pref + a[p] == half) {
cout << 1 << '\n';
printVec(a);
return;
}
ll d = half - pref;
vector<ll> first = a, second(n, 0);
first[p] -= d;
second[p] = d;
ll need = d;
for (int i = n - 1; i > p && need > 0; i--) {
ll take = min(first[i], need);
first[i] -= take;
second[i] = take;
need -= take;
}
cout << 2 << '\n';
printVec(first);
printVec(second);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) solve();
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
void printVec(const vector<ll>& v) {
for (int i = 0; i < (int)v.size(); i++) {
cout << v[i] << (i + 1 == (int)v.size() ? '\n' : ' ');
}
}
void solve() {
int n;
cin >> n;
vector<ll> a(n);
ll sum = 0, mx = 0;
for (ll &x : a) {
cin >> x;
sum += x;
mx = max(mx, x);
}
if (sum % 2 || mx * 2 > sum) {
cout << -1 << '\n';
return;
}
ll half = sum / 2;
ll pref = 0;
int p = 0;
while (p < n && pref + a[p] < half) {
pref += a[p];
p++;
}
if (p < n && pref + a[p] == half) {
cout << 1 << '\n';
printVec(a);
return;
}
ll d = half - pref;
vector<ll> first = a, second(n, 0);
first[p] -= d;
second[p] = d;
ll need = d;
for (int i = n - 1; i > p && need > 0; i--) {
ll take = min(first[i], need);
first[i] -= take;
second[i] = take;
need -= take;
}
cout << 2 << '\n';
printVec(first);
printVec(second);
}
int main() {
setIO();
int t;
cin >> t;
while (t--) solve();
}