This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);cerr.tie(0)
#define mp make_pair
#define xx first
#define yy second
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define all(x) x.begin(),x.end()
#define ff(i,a,b) for (int i = a; i < b; i++)
#define fff(i,a,b) for (int i = a; i <= b; i++)
#define bff(i,a,b) for (int i = b-1; i >= a; i--)
#define bfff(i,a,b) for (int i = b; i >= a; i--)
using namespace std;
long double typedef ld;
unsigned int typedef ui;
long long int typedef li;
pair<int,int> typedef pii;
pair<li,li> typedef pli;
pair<ld,ld> typedef pld;
vector<vector<int>> typedef graph;
unsigned long long int typedef ull;
//const int mod = 998244353;
const int mod = 1000000007;
//Note to self: Check for overflow
int t[2000006];
int dp[2000006];
int uzo[2000006]; //odakle sam uzo; -1 za "samo nastavi"
int k=1;
int mn[4444444],upd[4444444];
int l[44444444],r[44444444];
void Clear()
{
ff(i,1,2*k) mn[i]=0,upd[i]=0;
}
void Build(int n)
{
while (k<n) k*=2;
ff(i,0,k) l[i+k]=i,r[i+k]=i;
bff(i,1,k) l[i]=l[2*i],r[i]=r[2*i+1];
Clear();
}
void Upd(int p)
{
mn[p]+=upd[p];
if (p<k) upd[2*p]+=upd[p],upd[2*p+1]+=upd[p];
upd[p]=0;
}
void Add(int p, int ll, int rr, int x)
{
if (ll>r[p] || rr<l[p]) Upd(p);
else if (ll<=l[p] && rr>=r[p]) upd[p]+=x,Upd(p);
else Upd(p),Add(2*p,ll,rr,x),Add(2*p+1,ll,rr,x),mn[p]=min(mn[2*p],mn[2*p+1]);
}
int Min(int p, int ll, int rr)
{
if (ll>r[p] || rr<l[p]) return mod;
if (ll<=l[p] && rr>=r[p]) return Upd(p),mn[p];
return Upd(p),min(Min(2*p,ll,rr),Min(2*p+1,ll,rr));
}
int Walk(int p, int ll, int x) //ll znaci odakle Walkuje
{
Upd(p);
if (p<k) Upd(2*p),Upd(2*p+1);
if (mn[p]!=x) return -1;
if (r[p]<ll) return -1;
if (l[p]>=ll)
{
if (p>=k) return p-k;
if (mn[p]==mn[2*p]) return Walk(2*p,ll,x);
return Walk(2*p+1,ll,x);
}
else
{
int tind=Walk(2*p+1,ll,x);
if (tind==-1) return Walk(2*p,ll,x);
return tind;
}
}
int aliens(int n, int lambda, int T) //vraca koliko sam duseka strpao
{
Clear();
stack<int> kasni; //sorted decreasing - monotone stack
dp[n]=0,uzo[n]=0;
///segmentno stablo trazi index j sa idealnim dp[j]+cost(i,j-1)
bff(i,0,n)
{
dp[i]=dp[i+1],uzo[i]=uzo[i+1];
if (t[i]<=T)
{
Add(1,i+1,n,1); dp[i]++;
while (!kasni.empty() && kasni.top()-i+t[i]<=T)
{
Add(1,kasni.top()+1,n,1); dp[i]++;
kasni.pop();
}
}
else kasni.push(i);
int mozda=Min(1,i+1,n)+lambda;
if (mozda<dp[i])
{
dp[i]=mozda;
uzo[i]=uzo[Walk(1,i+1,mozda)]+1;
}
Add(1,i,i,dp[i]);
}
//cout<<"kazna: "<<lambda<<endl;
//fff(i,0,n) cout<<dp[i]<<" "; cout<<endl<<endl;
return uzo[0];
}
int main()
{
FAST;
int n,d,T; cin>>n>>d>>T;
ff(i,0,n) cin>>t[i];
Build(n+1);
int lo=-1,hi=1e9;
while (hi-lo>1)
{
int lambda=(lo+hi)/2;
if (aliens(n,lambda,T)>d) lo=lambda;
hi=lambda;
}
aliens(n,hi,T);
cout<<dp[0]-hi*uzo[0];
}
//Note to self: Check for overflow
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |