1+ /*
2+ Baltic 2021 The short shank; Redemption
3+ - Call prisoners with t[i] <= T "active" and others "passive"
4+ - We basically want to maximize the number of passive prisoners
5+ that don't protest
6+ - Consider a forest where:
7+ - The nodes are the passive prisoners
8+ - The parent of node i is the first prisoner to the right of
9+ i that won't rebel if there's a mattress to the left of i
10+ - We can find this forest by sweeping through the prisoners and
11+ using a stack
12+ - We know that par[i] > j iff there exists some k in [i, j)
13+ where k + T - t[k] >= j, and suffix maximums are monotonic
14+ - Next, we can just do the following D times:
15+ - Take the longest path in the forest from a root to a leaf
16+ - Subtract that path's length from the answer
17+ - Remove all nodes on that path from the graph
18+ - Since we traverse each node at most once, this runs in
19+ O(N log N) time (if we use a priority queue to find the
20+ longest path efficiently)
21+ */
22+
23+ #include < bits/stdc++.h>
24+ typedef long long ll;
25+ using namespace std ;
26+
27+ int depth[2000001 ], mx_child[2000001 ];
28+ vector<int > children[2000001 ];
29+
30+ int main () {
31+ cin.tie (0 )->sync_with_stdio (0 );
32+ int n, d, tx;
33+ cin >> n >> d >> tx;
34+
35+ int ans = n, glob_mx = 0 , loc_mx = 0 ;
36+ priority_queue<pair<int , int >> pq;
37+ stack<pair<int , int >> stck;
38+ for (int i = 1 ; i <= n; i++) {
39+ int t;
40+ cin >> t;
41+ glob_mx = max (glob_mx, i + tx - t);
42+ loc_mx = max (loc_mx, i + tx - t);
43+ if (stck.size ())
44+ stck.top ().second = max (stck.top ().second , loc_mx);
45+ if (t > tx) {
46+ if (glob_mx < i) ans--;
47+ else {
48+ depth[i] = 1 ;
49+ while (stck.size ()) {
50+ int node, tmp_mx;
51+ tie (node, tmp_mx) = stck.top ();
52+ if (tmp_mx >= i) break ;
53+ children[i].push_back (node);
54+ if (depth[node] + 1 > depth[i]) {
55+ depth[i] = depth[node] + 1 ;
56+ mx_child[i] = node;
57+ }
58+ stck.pop ();
59+ if (stck.size ())
60+ stck.top ().second = max (stck.top ().second , tmp_mx);
61+ }
62+ loc_mx = i + tx - t;
63+ stck.push ({i, loc_mx});
64+ }
65+ }
66+ }
67+ while (stck.size ()) {
68+ int root = stck.top ().first ;
69+ pq.push ({depth[root], root});
70+ stck.pop ();
71+ }
72+
73+ while (d-- && pq.size ()) {
74+ pair<int , int > curr = pq.top ();
75+ pq.pop ();
76+ ans -= curr.first ;
77+ int node = curr.second ;
78+ while (node) {
79+ for (int i : children[node]) if (i != mx_child[node])
80+ pq.push ({depth[i], i});
81+ node = mx_child[node];
82+ }
83+ }
84+ cout << ans;
85+ return 0 ;
86+ }
0 commit comments