Submission #1184501

#TimeUsernameProblemLanguageResultExecution timeMemory
1184501kl0989eThe short shank; Redemption (BOI21_prison)C++17
0 / 100
2096 ms101968 KiB
#include <bits/stdc++.h>
using namespace std;

#pragma GCC optimize("Ofast")

#define ll long long
#define fi first
#define se second
#define pb push_back
#define vi vector<int>
#define vl vector<ll>
#define pi pair<int, int>
#define pl pair<ll,ll>
#define all(x) (x).begin(),(x).end()

const int maxn=2e6+10;

vi a(maxn);
int n,d,t;

struct segTree {
	struct node {
		long double mn=1e9;
		long double lzy=0;
		int cnt=0;

		node(long double _mn=1e9): mn(_mn) {}
	};
	int sze;
	vector<node> nodes;

	node unite(node a, node b) {
		if (a.mn<=b.mn) {
			return a;
		}
		return b;
	}
	void push(int v, int tl, int tr) {
		nodes[v].mn+=nodes[v].lzy;
		if (tl!=tr) {
			nodes[2*v].lzy+=nodes[v].lzy;
			nodes[2*v+1].lzy+=nodes[v].lzy;
		}
		nodes[v].lzy=0;
	}

	segTree(int n): sze(n) {
		nodes.resize(4*n);
	}
	
	node get(int l, int r, int v, int tl, int tr) {
		push(v,tl,tr);
		if (l<=tl && tr<=r) {
			return nodes[v];
		}
		if (tr<l || r<tl) {
			return node();
		}
		int tm=tl+(tr-tl)/2;
		return unite(get(l,r,2*v,tl,tm),get(l,r,2*v+1,tm+1,tr));
	}
	node get(int l, int r) {
		return get(l,r,1,0,sze-1);
	}

	void update1(int l, int r, long double add, int v, int tl, int tr) {
		push(v,tl,tr);
		if (l<=tl && tr<=r) {
			nodes[v].lzy+=add;
			push(v,tl,tr);
			return;
		}
		if (tr<l || r<tl) {
			return;
		}
		int tm=tl+(tr-tl)/2;
		update1(l,r,add,2*v,tl,tm);
		update1(l,r,add,2*v+1,tm+1,tr);
		nodes[v]=unite(nodes[2*v],nodes[2*v+1]);
	}
	void update1(int l, int r, long double add) {
		update1(l,r,add,1,0,sze-1);
	}

	void update2(int ind, node val, int v, int tl, int tr) {
		push(v,tl,tr);
		if (tr<ind || ind<tl) {
			return;
		}
		if (tl==tr) {
			nodes[v]=unite(val,nodes[v]);
			return;
		}
		int tm=tl+(tr-tl)/2;
		update2(ind,val,2*v,tl,tm);
		update2(ind,val,2*v+1,tm+1,tr);
		nodes[v]=unite(nodes[2*v],nodes[2*v+1]);
	}
	void update2(int ind, node val) {
		update2(ind,val,1,0,sze-1);
	}
};

pi solve(long double pri) {
	segTree data(n+1);
	data.update2(0,0);
	for (int i=0; i<n; i++) {
		if (a[i]>t) {
			auto temp=data.get(0,n);
			temp.cnt++;
			temp.mn+=pri;
			data.update2(0,temp);
			data.update1(i+1,n,1);
		}
		else {
			data.update2(min(n,i+t-a[i]+1),data.get(0,min(n,i+t-a[i]+1)-1));
			data.update1(0,min(n,i+t-a[i]+1)-1,1e9);
		}
	}
	auto temp=data.get(0,n);
	pi ret={(int)round(temp.mn-pri*temp.cnt),temp.cnt};
	return ret;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> d >> t;
	int cnt=0;
	int dd=0;
    for (int i=0; i<n; i++) {
        cin >> a[i];
		if (a[i]<=t) {
			cnt++;
		}
		if (i>0 && a[i]>t && a[i-1]<=t) {
			dd++;
		}
    }
	d=min(dd,d);
	long double l=0,r=n;
	pi ans={1e9,1e9};
	while (1) {
		long double m=l+(r-l)/2;
		pi temp=solve(m);
		if (temp.se==d) {
			ans=min(ans,temp);
			break;
		}
		if (temp.se>d) {
			l=m;
		}
		else {
			ans=min(ans,temp);
			r=m;
		}
	}
	cout << cnt+ans.fi << '\n';
	/*vector<segTree> data(d+1,segTree(n+1));
	data[0].update2(0,0);
	for (int i=0; i<n; i++) {
		for (int k=d; k>=0; k--) {
			if (a[i]>t) {
				if (k<d) {
					data[k+1].update2(0,data[k].get(0,n).mn);
				}
				data[k].update1(i+1,n,1);
			}
			else {
				data[k].update2(min(n,i+t-a[i]+1),data[k].get(0,min(n,i+t-a[i]+1)-1).mn);
				data[k].update1(0,min(n,i+t-a[i]+1)-1,1e9);
			}
		}
	}
	ll ans=n;
	for (int k=0; k<=d; k++) {
		ans=min(ans,(ll)data[k].get(0,n).mn);
	}
	cout << ans+cnt << '\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...