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.
Think about what actually kills you. Sitting at chair only matters if it marks some future chair ; marking the past is harmless because time travel is still banned.
Suppose you decide the game will end when you first reach chair . Which earlier chairs can you safely sit on before that? A chair is safe exactly when its marked chair is either already passed or at/after .
For a fixed ending chair , the number you can sit on is:
Also, if chair is actually where the game stops, at least one earlier sat chair must mark it. Since is a permutation, that means the unique index with must satisfy .
Rewrite the fixed- count. Among , the bad ones are exactly those with . So the value is:
Now sweep from left to right and maintain how many “open intervals” currently contain .
Each index with creates a dangerous open interval . When sweeping , bad is the number of such intervals with . Then every with is a valid stopping chair, and the answer candidate is . Also consider surviving all chairs: sit on every with .
If you sit on chair , you mark chair .
If , that mark is harmless: the chair is already visited, or it is the current chair after you stand up. No future disaster.
If , then chair becomes a trap. When you reach it, the game ends immediately. So sitting at forbids you from safely visiting every chair in the open interval:
Those are the chairs where this decision is “active danger”. Cute little interval problem hiding inside a chair problem. Classic Codeforces nonsense, but friendly nonsense.
Assume the game first ends at chair .
Then we may sit only on chairs . For such an , sitting is valid if it does not mark a chair strictly between and ; otherwise the game would have ended earlier.
So chair is usable iff:
Equivalently, it is unusable iff:
Therefore, for a fixed , the best number of chairs we can sit on before reaching is:
But there is one more condition: chair must actually be marked before we get there. Since is a permutation, there is exactly one index such that:
Thus can be the stopping chair iff:
If that holds, our formula includes , because , so we can sit there and mark .
For every with , create interval . While sweeping , maintain:
These are exactly the earlier chairs that we cannot sit on if we want to reach .
Then for every valid stopping chair with , candidate answer is:
We can maintain with a difference array:
diff[i+1]++ and diff[p_i]--.If we visit all chairs, then every chair we sit on must satisfy:
because any would mark a future chair and eventually kill the run.
So another candidate is:
This also covers boring cases like , where the answer is if .
We prove the algorithm returns the maximum possible number of chairs sat on.
First, consider any strategy that ends for the first time at chair . It can only sit on chairs . If it sat on some with , then chair would have been marked before reaching it, so the game would have ended at , earlier than $r`. Contradiction. Hence every sat chair is counted by:
Also, for the game to end at , some earlier chair must mark . Since is a permutation, this is possible exactly when . So no strategy ending at can beat our candidate for .
Now suppose . Sit on every chair such that or , and skip all chairs with . Before reaching , none of the sat chairs marks a chair in that has not already been visited. Also, chair is included and marks . Therefore the game indeed reaches chairs , sits exactly the candidate number of times, and stops at . So the candidate is achievable.
Finally, if a strategy never stops, it cannot sit on any with , because that would mark a future chair eventually visited later. Conversely, sitting on all with never causes a future stop. Thus the all-visited candidate is exactly optimal among non-stopping strategies.
Taking the maximum over all stopping and non-stopping possibilities gives the global optimum.
The sweep and difference array are linear:
per test case, and the total input size is bounded by , so this easily fits. Memory usage is:
#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> p(n + 1), pos(n + 1), diff(n + 2, 0);
int survive_all = 0;
for (int i = 1; i <= n; i++) {
cin >> p[i];
pos[p[i]] = i;
if (p[i] <= i) {
survive_all++;
} else {
// Chair i is unusable for every stopping point r with i < r < p[i].
diff[i + 1]++;
diff[p[i]]--;
}
}
int ans = survive_all;
int bad = 0;
for (int r = 1; r <= n; r++) {
bad += diff[r];
if (pos[r] < r) {
ans = max(ans, (r - 1) - bad);
}
}
cout << ans << '\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> p(n + 1), pos(n + 1), diff(n + 2, 0);
int survive_all = 0;
for (int i = 1; i <= n; i++) {
cin >> p[i];
pos[p[i]] = i;
if (p[i] <= i) {
survive_all++;
} else {
// Chair i is unusable for every stopping point r with i < r < p[i].
diff[i + 1]++;
diff[p[i]]--;
}
}
int ans = survive_all;
int bad = 0;
for (int r = 1; r <= n; r++) {
bad += diff[r];
if (pos[r] < r) {
ans = max(ans, (r - 1) - bad);
}
}
cout << ans << '\n';
}
return 0;
}