제출 #867020

#제출 시각아이디문제언어결과실행 시간메모리
867020Mizo_CompilerThe short shank; Redemption (BOI21_prison)C++17
55 / 100
1914 ms524288 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef double ld; #define pb push_back #define sz(x) int(x.size()) #define all(x) x.begin(),x.end() #define F first #define S second const int N = 5e5+5; int n, a[N], d, t, nxt[N]; struct segtree { vector<int> t; void init(int sz) { t.resize(4*sz); } void upd(int l, int r, int x, int i, int v) { if (l == r) { t[x] = v; return; } int m = (l + r) >> 1; if (i <= m)upd(l, m, x*2+1, i, v); else upd(m+1, r, x*2+2, i, v); t[x] = min(t[x*2+1], t[x*2+2]); } int get(int li, int ri, int x, int l, int r) { if (li >= l && ri <= r)return t[x]; if (li > r || ri < l)return n; int m = (li + ri) >> 1; return min(get(li, m, x*2+1, l, r), get(m+1, ri, x*2+2, l, r)); } }; int main () { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> d >> t; int ans = 0; for (int i = 0; i < n; i++) { cin >> a[i]; } if (d == 1) { int pr[n], suf[n]; pr[0] = (a[0] <= t); int mn = a[0]+1; for (int i = 1; i < n; i++) { pr[i] = pr[i-1] + (min(mn, a[i]) <= t); mn = min(mn+1, a[i]+1); } set<int> s; suf[n-1] = (a[n-1] <= t); if (!suf[n-1])s.insert(n-1); for (int i = n-2; i >= 0; i--) { int cur = a[i]-i; suf[i] = suf[i+1] + (a[i] <= t); while (!s.empty()) { auto it = s.upper_bound(t-cur); if (it == s.begin())break; --it; suf[i]++; s.erase(it); } if (a[i] > t)s.insert(i); } ans = pr[n-1]; for (int i = 0; i+1 < n; i++) { ans = min(ans, pr[i] + suf[i+1]); } cout << ans << "\n"; return 0; } int idx[n]; idx[0] = 0; for (int i = 1; i < n; i++) { idx[i] = i; for (int j = i-1; j >= 0;) { if (a[j] + i - j <= t) { idx[i] = j; break; } j--; if (i - j > t)break; } } segtree ss; ss.init(n); for (int i = 0; i < n; i++) { if (a[i] > t && idx[i] == i)ss.upd(0, n-1, 0, i, -1); else ss.upd(0, n-1, 0, i, idx[i]); } for (int i = 0; i < n; i++) { nxt[i] = i; if (a[i] > t)continue; int l = i+1, r = n-1; while (l <= r) { int m = (l + r) >> 1; if (ss.get(0, n-1, 0, i+1, m) >= i) { nxt[i] = m; l = m+1; } else { r = m-1; } } } segtree s[d+1]; int dp[n][d+1]; for (int j = 0; j <= d; j++) { dp[n-1][j] = (a[n-1] <= t); s[j].init(n); s[j].upd(0, n-1, 0, n-1, (a[n-1] <= t) + n-1); } for (int i = n-2; i >= 0; i--) { for (int j = max(0, d-i); j <= d; j++) { if (a[i] > t) { dp[i][j] = dp[i+1][j]; s[j].upd(0, n-1, 0, i, dp[i][j] + i); continue; } dp[i][j] = (nxt[i]+1 < n ? dp[nxt[i]+1][j] + nxt[i]-i+1 : n-i); if (j && nxt[i] > i) { dp[i][j] = min(dp[i][j], s[j-1].get(0, n-1, 0, i+1, nxt[i]) - i); } s[j].upd(0, n-1, 0, i, dp[i][j] + i); } } cout << dp[0][d] << "\n"; }
#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...