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.
For a finished permutation, ask: which positions are not already equal to their index? The answer is entirely controlled by the first and last such position.
If a permutation has wrong positions from to , sorting exactly that segment fixes everything. Anything outside that segment must already be correct, so no shorter segment can work.
So the cost of a completed permutation is if it is already sorted, otherwise , where is the first index with and is the last index with .
A fixed positive value is forced: if , position is correct forever; if , position is wrong forever. Zeros are the only flexible positions.
If there are at least two zeros, every zero position can be made wrong by permuting the missing values with no fixed point. If there is exactly one zero at position , it is wrong only when the single missing value is not .
For any completed permutation , define a position as bad if .
The key fact is:
Why? Any segment we sort must contain every bad position, because positions outside the sorted segment will not change. So the segment must at least cover .
And sorting is enough: everything outside is already correct, meaning those outside positions contain exactly their own values. Since the whole array is a permutation, the values left inside must be exactly . Sorting them puts them in the right places. Nice and brutally simple.
So now the problem becomes: maximize the distance between the leftmost and rightmost bad positions after filling zeros.
Forced positions
For a nonzero position :
No magic. A fixed wrong value stays wrong.
Now consider zeros.
Let the zero positions be the places we need to fill, and let the missing numbers be the unused values. Their counts are equal.
If there is exactly one zero at position , then there is exactly one missing value :
If there are at least two zeros, then every zero position can be made bad at the same time. If a zero position would naturally receive its own index, just rotate/swap missing values among the zero positions. With at least two items, avoiding fixed points is possible here. Basically, don't hand anyone their own homework back.
Therefore, build the set of positions that can/ must be bad in the maximum construction:
Then the answer is:
Complexity
Each test case is processed in time and memory for marking used numbers. Across all tests, this is , which easily fits.
#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<int> used(n + 1, 0), zeros;
int l = n + 1, r = 0;
auto add_bad = [&](int pos) {
l = min(l, pos);
r = max(r, pos);
};
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (x == 0) {
zeros.push_back(i);
} else {
used[x] = 1;
if (x != i) add_bad(i);
}
}
if ((int)zeros.size() >= 2) {
add_bad(zeros.front());
add_bad(zeros.back());
} else if ((int)zeros.size() == 1) {
int missing = -1;
for (int x = 1; x <= n; x++) {
if (!used[x]) {
missing = x;
break;
}
}
if (missing != zeros[0]) add_bad(zeros[0]);
}
cout << (r == 0 ? 0 : r - l + 1) << '\n';
}
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;
while (t--) {
int n;
cin >> n;
vector<int> used(n + 1, 0), zeros;
int l = n + 1, r = 0;
auto add_bad = [&](int pos) {
l = min(l, pos);
r = max(r, pos);
};
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
if (x == 0) {
zeros.push_back(i);
} else {
used[x] = 1;
if (x != i) add_bad(i);
}
}
if ((int)zeros.size() >= 2) {
add_bad(zeros.front());
add_bad(zeros.back());
} else if ((int)zeros.size() == 1) {
int missing = -1;
for (int x = 1; x <= n; x++) {
if (!used[x]) {
missing = x;
break;
}
}
if (missing != zeros[0]) add_bad(zeros[0]);
}
cout << (r == 0 ? 0 : r - l + 1) << '\n';
}
return 0;
}