Submission #867043

#TimeUsernameProblemLanguageResultExecution timeMemory
867043Mizo_CompilerThe short shank; Redemption (BOI21_prison)C++17
10 / 100
208 ms53172 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];
	int dp[n][d+1];
	for (int j = 0; j <= d; j++) {
		dp[n-1][j] = (a[n-1] <= t);
		if (j < d)s[j].init(n);
		if (j < d)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);
			}
			if (j < d)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...