Submission #722773

#TimeUsernameProblemLanguageResultExecution timeMemory
722773JohannThe short shank; Redemption (BOI21_prison)C++14
80 / 100
2016 ms242656 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int, int> #define vb vector<bool> #define vi vector<int> #define vpii vector<pii> #define vvb vector<vb> #define vvi vector<vi> #define vvpii vector<vpii> #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() int N, D, T; vi P; vi protest; // state: 0 : never, 1 : save, -1 : changable vi trigger; // the rightmost prisoner to trigger [i], only for -1 vvi adj; // graph vi par; // parent vpii maxSubtree; pii NONE_PAIR = {-1, -1}; vvi nodeByLen; // nodes by their depth void dfs(int v) { if (maxSubtree[v] == NONE_PAIR) { if (sz(adj[v]) == 0) { maxSubtree[v] = {0, v}; return; } for (int u : adj[v]) dfs(u); for (int u : adj[v]) maxSubtree[v] = max(maxSubtree[v], maxSubtree[u]); ++maxSubtree[v].first; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> N >> D >> T; D = min(D, N); P.resize(N); for (int i = 0; i < N; ++i) cin >> P[i]; protest.assign(N, 0); trigger.assign(N, -1); stack<pii> blockers; // which range is blocked [i, j] inclusive for (int i = 0; i < N; ++i) { if (P[i] <= T) { protest[i] = 1; blockers.push({i, min(i + T - P[i], N)}); } else { while (!blockers.empty() && blockers.top().second < i) blockers.pop(); if (!blockers.empty()) protest[i] = -1, trigger[i] = blockers.top().first; } } adj.resize(N); par.assign(N, -1); stack<int> todo; for (int i = N - 1; i >= 0; --i) { if (protest[i] != -1) continue; while (!todo.empty() && trigger[todo.top()] > i) todo.pop(); if (!todo.empty()) adj[todo.top()].push_back(i), par[i] = todo.top(); todo.push(i); } maxSubtree.assign(N, NONE_PAIR); nodeByLen.resize(N); for (int i = 0; i < N; ++i) if (protest[i] == -1) { if (maxSubtree[i] == NONE_PAIR) dfs(i); nodeByLen[maxSubtree[i].first].push_back(i); } int idx = N - 1; while (D > 0 && idx >= 0) { if (sz(nodeByLen[idx]) == 0) { --idx; } else { int v = nodeByLen[idx].back(); nodeByLen[idx].pop_back(); if (protest[v] == -1) { --D; int u = maxSubtree[v].second; while (u != -1) { protest[u] = 0; u = par[u]; } } } } int ans = 0; for (int x : protest) if (x == -1 || x == 1) ++ans; cout << ans << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...