Submission #1020565

#TimeUsernameProblemLanguageResultExecution timeMemory
1020565vjudge1Roller Coaster Railroad (IOI16_railroad)C++17
34 / 100
451 ms304264 KiB
#include "railroad.h"
#include <bits/stdc++.h>

#define ll long long
#define pii pair<int,int>
#define F first
#define S second
#define sz(s) (int)s.size()
#define in insert
#define pb push_back
#define all(v) v.begin(),v.end()
#define mem(a,i) memset(a,i,sizeof(a))

using namespace std;

const int MAX=2e5+10;
const ll inf=1e18;

int n,cnt;
int t[4*MAX];
vector<int> g[6*MAX],g1[6*MAX];
vector<pii> vect;

void add(int x,int y){
    g[x].pb(y);
    g1[y].pb(x);
}

void build(int v,int tl,int tr){
    if(tl==tr){
        // cout<<"WOW "<<tl<<" "<<vect[tl].S<<"\n";
        t[v]=vect[tl].S;
        return;
    }
    int tm=(tl+tr)/2;
    build(2*v,tl,tm);
    build(2*v+1,tm+1,tr);
    t[v]=cnt++;
    add(t[v],t[2*v]);
    add(t[v],t[2*v+1]);
}

void update(int v,int tl,int tr,int l,int r,int i){
    if(l>r||tl>r||l>tr)return;
    if(l<=tl&&tr<=r){
        add(i,t[v]);
        return;
    }
    int tm=(tl+tr)/2;
    update(2*v,tl,tm,l,r,i);
    update(2*v+1,tm+1,tr,l,r,i);
}

vector<int> top;
bool use[6*MAX];

void dfs(int v){
    use[v]=1;
    for(auto to:g[v]){
        if(use[to])continue;
        dfs(to);
    }
    top.pb(v);
}

int cmp[MAX];

void dfs1(int v,int c){
    cmp[v]=c;
    use[v]=1;
    for(auto to:g1[v]){
        if(use[to])continue;
        dfs1(to,c);
    }
}

int dp[MAX];
int zs[MAX];
vector<int> gr[MAX*6];

void calc(int v){
    use[v]=1;
    for(auto to:gr[v]){
        if(!use[to])calc(to);
        dp[v]=max(dp[v],dp[to]);
    }
    dp[v]+=zs[v];
}



long long plan_roller_coaster(vector<int> s, vector<int> t) {
    n=sz(s);
    if(n<=16){
        ll dp[(1<<n)][n];
        for(int i=0;i<(1<<n);i++)for(int j=0;j<n;j++)dp[i][j]=inf;
        for(int i=0;i<n;i++)dp[(1<<i)][i]=0;
        for(int i=1;i<(1<<n);i++){
            if(__builtin_popcount(i)<=1)continue;
            for(int j=0;j<n;j++){
                if(!(i>>j&1))continue;
                for(int p=0;p<n;p++){
                    if(p==j||!(i>>p&1))continue;
                    // cout<<i-(1<<j)<<" "<<p<<" "<<dp[i-(1<<j)][p]<<" "<<max(0,t[p]-s[j])<<"\n";
                    dp[i][j]=min(dp[i][j],dp[i-(1<<j)][p]+max(0,t[p]-s[j]));
                }
                // cout<<i<<" "<<j<<" "<<dp[i][j]<<"\n";
            }
        }
        ll ans=inf;
        for(int i=0;i<n;i++)ans=min(ans,dp[(1<<n)-1][i]);
        return ans;
    }
    cnt=n;
    for(int i=0;i<n;i++){
        vect.pb({s[i],i});
    }
    sort(all(vect));
    build(1,0,n-1);
    vector<pii> tv;
    for(int i=0;i<n;i++){
        tv.pb({t[i],i});
    }
    sort(all(tv));
    reverse(all(tv));
    int r=n;
    for(int i=0;i<n;i++){
        while(r>0&&tv[i].F<=vect[r-1].F){
            r--;
        }
        update(1,0,n-1,r,n-1,tv[i].S);
    }
    for(int i=0;i<cnt;i++){
        if(!use[i])dfs(i);
    }
    mem(use,0);
    reverse(all(top));
    int c=0;
    for(int v:top){
        if(!use[v])dfs1(v,++c);
    }
    for(int i=0;i<n;i++)zs[cmp[i]]++;
    for(int i=0;i<cnt;i++){
        for(auto to:g[i]){
            if(cmp[i]!=cmp[to]){
                gr[cmp[i]].pb(cmp[to]);
            }
        }
    }
    mem(use,0);
    int ans=0;
    for(int i=1;i<=c;i++){
        if(!use[i])calc(i);
        ans=max(ans,dp[i]);
    }
    if(ans==n)return 0;
    return 1;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...