제출 #1369657

#제출 시각아이디문제언어결과실행 시간메모리
1369657BigBadBullyThe short shank; Redemption (BOI21_prison)C++20
80 / 100
2099 ms213696 KiB
#include <bits/stdc++.h>
using namespace std;
//#define int long long
#define pii pair<int, int>
#define ff first
#define ss second
#define tri array<int, 3>
//const int inf = 2e18;
const int mod = 1e9+7;
const int mxn = 1e6 + 1;
vector<int> fact(mxn+1,1),invfact(mxn+1,1),mpf(mxn+1,0);


int exp(int x, int n)
{
    int res = 1;
    for (; n > 0; res = (n % 2 ? res * x % mod : res), x = x * x % mod, n /= 2)
        ;
    return res;
}

int inv(int x)
{
    return exp(x, mod - 2);
}

void init()
{
    for(int i = 1; i <= mxn; i++)
        fact[i]=fact[i-1]*i%mod;
    invfact[mxn] = inv(fact[mxn]);
    for(int i = mxn-1; i >= 0; i--)
        invfact[i]=invfact[i+1]*(i+1)%mod;
    mpf[1]=1;
    for(int i = 2; i <= mxn; i++)
        if(!mpf[i])
            for(int j = i;j <= mxn;j+=i)
                if(!mpf[j])
                    mpf[j]=i;
}

int ncr(int n,int r)
{
    if(n<r ||n<0||r<0)
        return 0;
    return fact[n]*invfact[r]%mod*invfact[n-r]%mod;
}

struct seggy{
    int n;
    vector<int> t,lazy;
    seggy(int sz)
    {
        n = sz;
        t.resize(4*n,0);
        lazy.resize(4*n,0);
    }
    void pass(int l,int r,int idx){
        if(lazy[idx]==0)return;
        t[idx]+=lazy[idx];
        if(l!=r)
        {
            lazy[2*idx]+=lazy[idx];
            lazy[2*idx+1]+=lazy[idx];
        }
        lazy[idx]=0;
    }
    int query(int l,int r,int idx)
    {
        pass(l,r,idx);
        if(l==r)return l;
        int mid = l+r>>1;
        pass(l,mid,2*idx);
        pass(mid+1,r,2*idx+1);
        if(t[2*idx]>t[2*idx+1])
            return query(l,mid,2*idx);
        return query(mid+1,r,2*idx+1);
    }
    int gt()
    {
        return query(0,n-1,1);
    }
    void update(int l,int r,int L,int R,int idx,int x)
    {
        pass(l,r,idx);
        if(l>R||r<L)return;
        if(l>=L&&r<=R)
        {
            lazy[idx]+=x;
            pass(l,r,idx);
            return;
        }
        int mid = l+r>>1;
        update(l,mid,L,R,2*idx,x);
        update(mid+1,r,L,R,2*idx+1,x);
        t[idx]=max(t[2*idx],t[2*idx+1]);
    }
    void update(int l,int r,int x)
    {
        update(0,n-1,l,r,1,x);
    }
};

void solve()
{
    int n,d,t;
    cin>>n>>d>>t;
    vector<int> v(n);
    for(int&x:v)cin>>x;
    for(int i = 0; i < n;i++)v[i]-=i;
    set<int> moguc;
    for(int i=0;i<n;i++)moguc.insert(i);
    vector<int> id(n);
    iota(id.begin(),id.end(),0);
    sort(id.begin(),id.end(),[&](int a,int b){return v[a]>v[b];});
    vector<int> sg(n,-1);
    int mn = 0;
    {
        int j = 0;
        for(int i = 0; i < n; i++)
        {
            while(j<n&&v[id[j]]>t-i)
            {
                moguc.erase(id[j]);
                j++;
            }
            auto it = moguc.upper_bound(i);
            if(it!=moguc.begin())
            {
                --it;
                sg[i]=*it+1;
                if(sg[i]>i)sg[i]=-1,mn++;
            }
        }
    }
    int k = n-count(sg.begin(),sg.end(),-1);
    vector<int> par(k+1,0);
    vector<int> here(k+1,1);
    vector<int> memo(k+1,-1);
    par[0]=-1;
    {
        stack<int> s;
        int sen = 0;
        for(int i = n-1; i >= 0; i--)  
            if(sg[i]>=0)
            {
                sen++;
                memo[sen]=i;
                while(s.size()&&sg[i]<sg[memo[s.top()]])
                    s.pop();
                par[sen]=(s.size()?s.top():0);
                s.push(sen);
            }
    }
    vector<vector<int>> g(k+1);
    for(int i = 1; i <= k; i++)
        g[par[i]].push_back(i);
    vector<int> depth(n,0);
    vector<int> st(k+1),en(k+1);
    seggy mile(k+1);
    int timer = 0;
    function<void(int,int)> dfs = [&](int cur,int prev)
    {
        depth[cur]=depth[prev]+here[cur];
        mile.update(timer,timer,depth[cur]);
        st[cur]=timer++;
        for(int a:g[cur])
            if(a!=prev)
                dfs(a,cur);
        en[cur]=timer-1;
    };
    dfs(0,0);
    function<void(int)> del = [&](int cur){
        while(cur>=0&&here[cur])
        {
            mile.update(st[cur],en[cur],-1);
            here[cur]=0;
            cur=par[cur];
        }
    };
    int it = 0;
    int ans = mn+k+1;
    for(;it<min(d,k);it++)
    {
        int idx = mile.gt();
        ans-=mile.t[1];
        del(idx);
        depth.assign(n,0);
    }
    cout<<ans-(k==0)<<'\n';
}


signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //init();

    int t=1;
    //cin >>t;
    while(t--)solve();
        
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…