Submission #754883

#TimeUsernameProblemLanguageResultExecution timeMemory
754883alexander707070Roller Coaster Railroad (IOI16_railroad)C++14
30 / 100
152 ms9432 KiB
#include <bits/stdc++.h>
 
using namespace std;

const long long inf=1e15;
 
int n,fullmask;
pair<long long,long long> a[200007];
int ind[200007],curr;
 
bool cmp(int x,int y){
    return a[x].second>a[y].second;
}

int tree[4*200007],pos,cnt;

void build(int v,int l,int r){
    if(l==r){
        tree[v]=l;
    }else{
        int tt=(l+r)/2;
        build(2*v,l,tt);
        build(2*v+1,tt+1,r);
        tree[v]=l;
    }
}

void update(int v,int l,int r,int pos){
    if(l==r){
        tree[v]=n+1;
    }else{
        int tt=(l+r)/2;
        if(pos<=tt)update(2*v,l,tt,pos);
        else update(2*v+1,tt+1,r,pos);
        tree[v]=min(tree[2*v],tree[2*v+1]);
    }
}

int getmin(int v,int l,int r,int ll,int rr){
    if(ll>rr)return n+1;
    if(l==ll and r==rr){
        return tree[v];
    }else{
        int tt=(l+r)/2;
        return min( getmin(2*v,l,tt,ll,min(tt,rr)) , getmin(2*v+1,tt+1,r,max(tt+1,ll),rr) );
    }
}

long long dp[17][65536];
bool li[17][65536];

long long ff(int last,int mask){
    if(mask==fullmask)return 0;

    if(li[last][mask])return dp[last][mask];
    li[last][mask]=true;
    dp[last][mask]=inf;

    for(int i=0;i<n;i++){
        if(((1<<i)&mask)>0)continue;
        dp[last][mask]=min(dp[last][mask],ff(i,mask|i)+max(a[i+1].second-a[last].first,0LL));
    }

    return dp[last][mask];
}

long long plan_roller_coaster(vector<int> s,vector<int> t){

    n=s.size();
    for(int i=1;i<=n;i++){
        a[i]={s[i-1],t[i-1]};
        ind[i]=i;
    }

    if(n<=16){
        fullmask=(1<<n)-1;
        a[n].first=inf;
        return ff(n,0);
    }

    sort(a+1,a+n+1);
    sort(ind+1,ind+n+1,cmp);
    build(1,1,n);

    for(int i=1;i<=n;i++){
        curr=ind[i];
        int l=0,r=n+1,tt;
        while(l+1<r){
            tt=(l+r)/2;
            if(a[curr].second<=a[tt].first){
                r=tt;
            }else{
                l=tt;
            }
        }
        pos=getmin(1,1,n,r,n);
        if(pos==curr)pos=getmin(1,1,n,pos+1,n);

        if(pos==n+1)cnt++;
        else update(1,1,n,pos);
    }

    if(cnt>1)return 1;

    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...