Submission #1278120

#TimeUsernameProblemLanguageResultExecution timeMemory
1278120vlomaczkThe short shank; Redemption (BOI21_prison)C++20
80 / 100
2044 ms191816 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
typedef long double ld;
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

int M = 1e6 + 10;
vector<vector<int>> g(M);
vector<pair<int, int>> h(M);

struct Fenwick {
	vector<ll> bit; ll n;
	Fenwick(ll n_) : n(n_), bit(n_+1, -1) {}
	void update(ll i, ll val) { for(; i<=n; i+=i & -i) bit[i] = max(bit[i], val); }
	ll query(ll i) { ll ans=-1; for(; i>0; i-=i & -i) ans = max(ans, bit[i]); return ans; }
};

struct BIT {
	vector<ll> bit; ll n;
	BIT(ll n_) : n(n_), bit(n_+1, M) {}
	void update(ll i, ll val) { for(; i<=n; i+=i&(-i)) bit[i] = min(bit[i], val); }
	ll query(ll i) { ll ans=M; for(; i>0; i-=(i&(-i))) ans = min(ans, bit[i]); return ans; }
};

void dfs(int v) {
	h[v] = {1,-1};
	for(auto u : g[v]) {
		dfs(u);
		h[v] = max(h[v], {h[u].first+1, u});
	}
}

int best = 0;
priority_queue<pair<int, int>> pq;

void add_roots(int v) {
	if(h[v].second==-1) return;
	for(auto u : g[v]) {
		if(h[v].second==u) add_roots(u);
		else pq.push({h[u].first, u});
	}
}

int main() {
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);

	ll n, d, T;
	cin >> n >> d >> T;
	vector<ll> t(n);
	map<ll, ll> mapa;
	for(int i=0; i<n; ++i) {
		cin >> t[i];
		mapa[i-t[i]] = 1;
		mapa[i-T] = 1;
	}
	int nxt = 2*n;
	for(auto&[a,b] : mapa) b = nxt--;
	ll inf = 1e18;
	ld start = 0;
	ld koniec = 1e18;
	Fenwick bit(2*n);
	vector<ll> left(n);
	int ans = 0;
	for(int i=0; i<n; ++i) {
		bit.update(mapa[i-t[i]], i);
		left[i] = bit.query(mapa[i-T]);
		if(left[i]!=-1) ans++;
	}
	BIT bit2(n);
	vector<int> roots;
	vector<int> par(n);
	for(int i=n-1; i>=0; --i) {
		if(left[i]==i || left[i]==-1) continue;
		par[i] = bit2.query(left[i]+1);
		bit2.update(left[i]+1, i);
		if(par[i]==M) roots.push_back(i);
		else g[par[i]].push_back(i);
	}
	for(auto r : roots) {
		dfs(r);
		pq.push({h[r].first, r});
	}
	while(d > 0) {
		auto[ile, v] = pq.top(); pq.pop();
		best += ile;
		add_roots(v);
		--d;
	}
	cout << ans-best << "\n";

	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...