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.
An operation decreases the sum exactly when the chosen set's sum is not divisible by its size. The actual "decrease the smallest values" rule matters later, but first find when no decreasing operation exists.
For a fixed size , if every -element subset has sum divisible by , compare two subsets that differ in exactly one element. Their sums differ by , so all elements must be congruent modulo .
So a dead/terminal array is exactly: all elements have the same residue modulo every , and the total sum is divisible by . That is the whole "no move works" condition.
There is one extra finite case: if decreasing the globally smallest element by makes the array terminal, then every possible decreasing move is forced to do exactly that. After that, you're stuck.
If neither the current array nor array with its minimum decreased by 1 is terminal, the answer is . Bad states can be pushed into a parity setup where the current minimum can always be paired with an opposite-parity anchor and decreased forever. The implementation is literally just checking those two terminal tests.
The problem looks like it wants simulation. It absolutely does not. The whole thing collapses to checking two states:
If either one is a terminal state, we know the finite answer. Otherwise the sum can go to , so print -1.
When Is An Array Terminal?
Call an array terminal if no operation can decrease the sum.
Take any chosen set of size . Its sum is , and the operation decreases the total sum by
So the operation changes nothing exactly when is divisible by .
Therefore an array is terminal iff:
every subset of size has sum divisible by , for every .
Now fix some . Suppose every -subset has sum divisible by . Pick two indices . Since , we can choose the other elements the same way and compare two subsets:
Both sums are , so their difference is also :
So for every , all elements must be congruent modulo .
For , there is only one subset: the whole array. So we only need
Thus the terminal condition is:
That is the main number theory bit. Tiny, but mean.
The One-Step Case
Suppose the current array is not terminal, but after decreasing a smallest element by , it becomes terminal.
Let that terminal array be , and the current array be , where only the smallest element differs:
Now look at any chosen set .
Since is a globally smallest element, when the remainder is , the operation decreases exactly that element. So every useful move sends us straight to the terminal array.
Answer: original sum minus .
Why Everything Else Is Infinite
Now assume neither the original array nor the array after decreasing the smallest element by is terminal.
Then the array is not just "not done"; it is doomed. There is a way to keep decreasing forever.
The key parity trap is this:
If, after excluding the current smallest element, there are elements of both parities, then the current smallest can be decreased forever. When the smallest is even, pair it with an odd anchor. When it is odd, pair it with an even anchor. A pair with odd sum has remainder , and the smaller element is the current minimum, so it gets decreased. Repeat. Free infinite descent, no fancy machinery.
If the remaining elements do not already contain both parities, then all of them have the same parity. Any legal operation performed completely among those remaining elements flips the parity of at least one of them and not all of them, which creates the parity trap. There is one annoying edge case where it only decreases another copy of the minimum; doing the analogous operation once more gives two lowered elements, and the trap appears anyway. This is the part where the operation's "decrease the smallest values" rule actually matters.
If no such operation exists among the remaining elements, then the only useful moves must involve the global minimum. If decreasing that minimum once made the whole array terminal, we would be in the one-step case above. But we assumed it does not. So either some move decreases the minimum together with another element, immediately creating the parity trap, or we can keep decreasing the minimum until such a move appears. If it never appears, the minimum is already going down forever. Either way, the sum is unbounded below.
So the classification is complete:
-1.Checking Terminal Fast
For , directly test all moduli .
For , the condition forces all elements to be equal. Why? If all elements are congruent modulo every number from through , then every difference is divisible by
But the values we check are between and , so a nonzero difference cannot be that large in divisibility terms. Therefore every difference is .
So for large , terminal just means all values are equal, plus the sum divisibility check. The divisibility is automatic when all values are equal, but keeping the check makes the function uniform and harmless.
Complexity: sorting dominates, so per test case, with total .
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
bool good(const vector<ll>& a) {
int n = (int)a.size();
ll sum = 0;
for (ll x : a) sum += x;
if (sum % n != 0) return false;
if (n > 23) {
for (int i = 1; i < n; i++) {
if (a[i] != a[0]) return false;
}
return true;
}
for (int mod = 2; mod < n; mod++) {
int r = (int)(a[0] % mod);
for (ll x : a) {
if (x % mod != r) return false;
}
}
return true;
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<ll> a(n);
ll sum = 0;
for (ll& x : a) {
cin >> x;
sum += x;
}
sort(a.begin(), a.end());
if (good(a)) {
cout << sum << '\n';
continue;
}
a[0]--;
sum--;
if (good(a)) cout << sum << '\n';
else cout << -1 << '\n';
}
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
bool good(const vector<ll>& a) {
int n = (int)a.size();
ll sum = 0;
for (ll x : a) sum += x;
if (sum % n != 0) return false;
if (n > 23) {
for (int i = 1; i < n; i++) {
if (a[i] != a[0]) return false;
}
return true;
}
for (int mod = 2; mod < n; mod++) {
int r = (int)(a[0] % mod);
for (ll x : a) {
if (x % mod != r) return false;
}
}
return true;
}
int main() {
setIO();
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<ll> a(n);
ll sum = 0;
for (ll& x : a) {
cin >> x;
sum += x;
}
sort(a.begin(), a.end());
if (good(a)) {
cout << sum << '\n';
continue;
}
a[0]--;
sum--;
if (good(a)) cout << sum << '\n';
else cout << -1 << '\n';
}
}