제출 #408786

#제출 시각아이디문제언어결과실행 시간메모리
408786rocks03The short shank; Redemption (BOI21_prison)C++14
70 / 100
2088 ms152212 KiB
#include<bits/stdc++.h> using namespace std; #define ll long long #define pii pair<int, int> #define pll pair<ll, ll> #define ff first #define ss second #define pb push_back #define SZ(x) ((int)(x).size()) #define all(x) x.begin(), x.end() #define debug(x) cout << #x << ": " << x << " " #define nl cout << "\n" #define rep(i, a, b) for(int i = (a); i <= (b); i++) #define per(i, a, b) for(int i = (a); i >= (b); i--) mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); const int MAXN = 2e6+100; int N, D, T, a[MAXN]; vector<int> g[MAXN]; void compute_time(){ stack<int> st; rep(i, 0, N - 1){ while(!st.empty()){ int j = st.top(); if(a[j] + i - j > T) st.pop(); else break; } if(a[i] <= T){ g[i].pb(i); } else{ if(!st.empty()) g[st.top()].pb(i); } st.push(i); } } struct Node{ pll dp = {0, 0}; int lazy = 0; }; class SegmentTree{ public: vector<Node> st; void build(int n){ st = vector<Node>(4 * n); } void push(int i){ if(st[i].lazy){ int cl = 2 * i + 1, cr = 2 * i + 2; st[cl].dp.ff += st[i].lazy, st[cl].lazy += st[i].lazy; st[cr].dp.ff += st[i].lazy, st[cr].lazy += st[i].lazy; st[i].lazy = 0; } } void merge(int i){ int cl = 2 * i + 1, cr = 2 * i + 2; if(st[cl].dp < st[cr].dp){ st[i].dp = st[cl].dp; } else{ st[i].dp = st[cr].dp; } } void add(int i, int l, int r, int ql, int qr, int k){ if(ql <= l && r <= qr){ st[i].dp.ff += k, st[i].lazy += k; return; } if(qr < l || ql > r) return; push(i); int m = (l + r) / 2; add(2 * i + 1, l, m, ql, qr, k); add(2 * i + 2, m + 1, r, ql, qr, k); merge(i); } void set(int i, int l, int r, int p, pll val){ if(l == r){ st[i].dp = val; st[i].lazy = 0; return; } else{ push(i); int m = (l + r) / 2; if(p <= m) set(2 * i + 1, l, m, p, val); else set(2 * i + 2, m + 1, r, p, val); merge(i); } } pll query(int i, int l, int r, int ql, int qr){ if(ql <= l && r <= qr){ return st[i].dp; } if(qr < l || ql > r) return {LLONG_MAX, 0}; push(i); int m = (l + r) / 2; pll ans1 = query(2 * i + 1, l, m, ql, qr); pll ans2 = query(2 * i + 2, m + 1, r, ql, qr); if(ans1 < ans2) return ans1; else return ans2; } } st; pll compute_dp(ll penalty){ st.build(N + 1); pll ans; per(i, N - 1, 0){ for(int j : g[i]){ st.add(0, 0, N, j + 1, N, +1); } pll val = st.query(0, 0, N, i + 1, N); val.ff += penalty, val.ss += 1; pll val2 = st.query(0, 0, N, N, N); if(val > val2) val = val2; st.set(0, 0, N, i, val); if(i == 0) ans = val; } return ans; } void solve(){ cin >> N >> D >> T; rep(i, 0, N - 1) cin >> a[i]; compute_time(); int l = -1, r = N + 1; while(r - l > 1){ int m = (l + r) / 2; pll ans = compute_dp(m); if(ans.ss <= D) r = m; else l = m; } pll ans = compute_dp(r); cout << ans.ff - D * r; } int main(){ ios_base::sync_with_stdio(false), cin.tie(nullptr); solve(); 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...