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.
Only two arrays change in one operation: the source array that loses one element, and the destination array that gains it. Start from the original total MEX sum and add the two local changes.
For removing a value from an array with MEX : the MEX changes only if and this occurrence is the only copy of . Then the new MEX becomes exactly .
For adding a value to an array with MEX : the MEX changes only if . Then the new MEX jumps to the first missing number after .
So each array only needs three things: its MEX , the next missing number after , and which values appear exactly once. Everything else is dead weight for MEX changes.
Let be the original sum of MEXes and the total number of elements. The baseline contributes . Add removal deltas counted for every possible destination, and addition deltas counted from all source elements outside the destination array.
Let the original MEX of array be , and let
There are possible operations, because every element occurrence can be moved to any other array. If nothing changed, every operation would contribute , so the baseline is
Now stop thinking about the whole operation. Only two arrays matter: the source loses one element, and the destination gains one element. Everyone else just sits there looking busy.
For an operation moving value from source to destination , its value is
where is the MEX change after removing this specific occurrence from , and is the MEX change after adding to .
For removing, suppose .
If , removing cannot affect the presence of all values , and was already missing. So the MEX stays .
If , then is currently present. Removing it only matters if it was present exactly once. In that case becomes the smallest missing number, so the new MEX is .
Therefore
This delta is counted once for every possible destination, so the total removal contribution is
For adding, again let .
Adding changes the MEX only if , because is the first missing value. If , then is still missing, so the MEX remains .
When we add , the new MEX becomes the first missing value greater than . Call it . Then
For destination , this delta is paid for every occurrence of value outside array . Since is missing from , that is just the global number of occurrences of .
So the total addition contribution is
Combine everything:
To compute the data for one array, count only values up to . An array of length cannot force its MEX or next missing value past , so huge values are MEX noise.
For each array:
All arithmetic should be long long. Complexity is
per test case, with linear memory. Reset only touched frequency entries; clearing giant arrays every test is the kind of tiny-looking mistake that nukes performance.
#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 int MAXA = 1000000;
vector<int> globalCnt(MAXA + 2, 0);
while (T--) {
int n;
cin >> n;
vector<vector<int>> a(n);
vector<int> len(n);
vector<int> touchedGlobal;
int totalLen = 0;
for (int i = 0; i < n; i++) {
cin >> len[i];
totalLen += len[i];
a[i].resize(len[i]);
for (int &x : a[i]) {
cin >> x;
if (globalCnt[x] == 0) touchedGlobal.push_back(x);
globalCnt[x]++;
}
}
ll mexSum = 0;
ll removeDeltaSum = 0;
ll addDeltaSum = 0;
vector<int> freq(totalLen + 3, 0);
vector<int> touched;
for (int i = 0; i < n; i++) {
touched.clear();
for (int x : a[i]) {
if (x <= len[i] + 1) {
if (freq[x] == 0) touched.push_back(x);
freq[x]++;
}
}
int mex = 0;
while (freq[mex] > 0) mex++;
int nextMissing = mex + 1;
while (freq[nextMissing] > 0) nextMissing++;
mexSum += mex;
addDeltaSum += 1LL * (nextMissing - mex) * globalCnt[mex];
for (int x : touched) {
if (x < mex && freq[x] == 1) {
removeDeltaSum += x - mex;
}
}
for (int x : touched) freq[x] = 0;
}
ll ans = mexSum * totalLen * (n - 1)
+ removeDeltaSum * (n - 1)
+ addDeltaSum;
cout << ans << '\n';
for (int x : touchedGlobal) globalCnt[x] = 0;
}
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 int MAXA = 1000000;
vector<int> globalCnt(MAXA + 2, 0);
while (T--) {
int n;
cin >> n;
vector<vector<int>> a(n);
vector<int> len(n);
vector<int> touchedGlobal;
int totalLen = 0;
for (int i = 0; i < n; i++) {
cin >> len[i];
totalLen += len[i];
a[i].resize(len[i]);
for (int &x : a[i]) {
cin >> x;
if (globalCnt[x] == 0) touchedGlobal.push_back(x);
globalCnt[x]++;
}
}
ll mexSum = 0;
ll removeDeltaSum = 0;
ll addDeltaSum = 0;
vector<int> freq(totalLen + 3, 0);
vector<int> touched;
for (int i = 0; i < n; i++) {
touched.clear();
for (int x : a[i]) {
if (x <= len[i] + 1) {
if (freq[x] == 0) touched.push_back(x);
freq[x]++;
}
}
int mex = 0;
while (freq[mex] > 0) mex++;
int nextMissing = mex + 1;
while (freq[nextMissing] > 0) nextMissing++;
mexSum += mex;
addDeltaSum += 1LL * (nextMissing - mex) * globalCnt[mex];
for (int x : touched) {
if (x < mex && freq[x] == 1) {
removeDeltaSum += x - mex;
}
}
for (int x : touched) freq[x] = 0;
}
ll ans = mexSum * totalLen * (n - 1)
+ removeDeltaSum * (n - 1)
+ addDeltaSum;
cout << ans << '\n';
for (int x : touchedGlobal) globalCnt[x] = 0;
}
return 0;
}