Submission #866984

#TimeUsernameProblemLanguageResultExecution timeMemory
866984Mizo_CompilerThe short shank; Redemption (BOI21_prison)C++17
45 / 100
2021 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];
	}
	int idx[n];
	idx[0] = 0;
	for (int i = 1; i < n; i++) {
		idx[i] = i;
		for (int j = i-1; j >= 0; j--) {
			if (a[j] + i - j <= t) {
				idx[i] = j;
				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 = 0; 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";
}

Compilation message (stderr)

prison.cpp: In function 'int main()':
prison.cpp:39:6: warning: unused variable 'ans' [-Wunused-variable]
   39 |  int ans = 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...