답안 #718759

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
718759 2023-04-04T17:32:40 Z n0sk1ll The short shank; Redemption (BOI21_prison) C++14
0 / 100
0 ms 340 KB
#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
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 0 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -