Submission #102008

#TimeUsernameProblemLanguageResultExecution timeMemory
102008scanhexRailway Trip (JOI17_railway_trip)C++17
30 / 100
2057 ms45736 KiB
#include <bits/stdc++.h>
 
using namespace std;
using nagai = long long;
#define sz(x) int((x).size())
 
const int LG=17;
const int N=1<<LG;
const int oo=0x3f3f3f3f;
int n,k,q;
int l[N];
int go[LG][N][2];
int cost[LG][N][2];
vector<int>occ[N];
 
int count_occ(int lev,int l,int r){
    return lower_bound(occ[lev].begin(),occ[lev].end(),r)-lower_bound(occ[lev].begin(),occ[lev].end(),l);
}
 
pair<int,int> mx[2*N];
void build(){
    for(int i=0;i<n;++i)
        mx[N+i]={l[i],i};
    for(int i=n;i<N;++i)
        mx[N+i]={0,0};
    for(int i=N-1;i>=0;--i)
        mx[i]=max(mx[2*i],mx[2*i+1]);
}
 
int ft(int x,int l,int r,int ql,int qx){
    if(r<=ql||mx[x].first<qx)
        return -1;
    if(r-l==1)
        return mx[x].second;
    int m=(l+r)/2;
    int ans=ft(x*2,l,m,ql,qx);
    if(ans==-1)ans=ft(x*2+1,m,r,ql,qx);
    return ans;
}
 
int lst(int x,int l,int r,int qr,int qx){
    if(l>=qr||mx[x].first<qx)
        return -1;
    if(r-l==1)
        return mx[x].second;
    int m=(l+r)/2;
    int ans=lst(x*2+1,m,r,qr,qx);
    if(ans==-1)ans=lst(x*2,l,m,qr,qx);
    return ans;
}
 
pair<int,int> getmax(int l,int r){
     l+=N;
     r+=N;
     pair<int,int> ans={-1,-1};
     while(l<r){
          if(l&1)
              ans=max(ans,mx[l++]);
          if(r&1)
              ans=max(ans,mx[--r]);
          l/=2,r/=2;
     }
     return ans;
}
 
int pref[N],suff[N];
 
int cntcalled=0;
pair<int,int> goleri(int x,int lev,int dir,int from,int mx=oo){
	if(mx<0)return {x,0};
    ++cntcalled;
    if(l[x]>=lev)return {x,0};
    if(l[go[0][x][dir]]>=lev)
        return {go[0][x][dir],cost[0][x][dir]};
    if(dir==0&&l[pref[x]]<lev)
        return {pref[x],oo};
    if(dir==1&&l[suff[x]]<lev)
        return {suff[x],oo};
    for(int i=from;i>=0;--i){
        if(l[x]+(1<<i)<=lev){
            auto p=goleri(go[i][x][dir],lev,dir,i-1,mx-cost[i][x][dir]);
            p.second+=cost[i][x][dir];
			if(l[go[i][x][dir]]>=lev)
				return p;
//          auto q=make_pair(go[i][x][1^dir],cost[i][x][1^dir]+1);
            auto q=goleri(go[i][x][1^dir],lev,dir,i-1,min(mx,p.second)-cost[i][x][1^dir]);
            q.second+=cost[i][x][1^dir];
            if(dir==0&&q.first>x||dir==1&&q.first<x)
                ++q.second,q.first=p.first;
            return {p.first,min(q.second,p.second)};
        }
    }
    return {x,oo};
    exit(239);
}
 
 
inline pair<int,int> gole(int x,int lev,int from=LG-1){
    return goleri(x,lev,0,from);
}
inline pair<int,int> gori(int x,int lev,int from=LG-1){
    return goleri(x,lev,1,from);
}
 
int d[N];
 
int stup_calc(int a,int b){
    if(b<a)
        swap(a,b);
    int ans=0;
    for(int i=a;i<=b;++i){
        if(l[i]>=l[a]||l[i]>=l[b])
            ++ans;
    }
    return ans-1;
}
struct cmp{
     bool operator()(int a,int b) const{
         if(d[a]!=d[b])
             return d[a]<d[b];
         return a<b;
     };
};
int stupid(int a,int b){
    memset(d,0x3f,sizeof d);
    d[a]=0;
    set<int,cmp>st;
    st.insert(a);
    while(st.size()){
         int x=*st.begin();
         st.erase(st.begin());
         if(x==b)
             return d[x];
         for(int y=0;y<n;++y){
             int v=stup_calc(x,y);
             if(d[x]+v<d[y]){
                  st.erase(y);
                  d[y]=d[x]+v;
                  st.insert(y);
             }
         }
    }
    assert(false);
}
 
bool st=false;
 
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    n=100000,k=-1,q=100000;
	cin>>n>>k>>q;
    for(int i=0;i<n;++i){
		cin>>l[i];
        --l[i];
        occ[l[i]].push_back(i);
    }
    memset(cost,0,sizeof cost);
    memset(go,0,sizeof go);
    build();
    pref[0]=0;
    for(int i=1;i<n;++i)
        if(l[i]>=l[pref[i-1]])pref[i]=i;
        else pref[i]=pref[i-1];
    suff[n-1]=n-1;
    for(int i=n-2;i>=0;--i)
        if(l[i]>=l[suff[i+1]])suff[i]=i;
        else suff[i]=suff[i+1];
    for(int i=0;i<n;++i){
        if((go[0][i][0]=lst(1,0,N,i,l[i]+1))==-1)
            go[0][i][0]=i;
        else
            cost[0][i][0]=count_occ(l[i],go[0][i][0],i+1);
        if((go[0][i][1]=ft(1,0,N,i,l[i]+1))==-1)
            go[0][i][1]=i;
        else
            cost[0][i][1]=count_occ(l[i],i,go[0][i][1]);
        if(go[0][i][1]!=i&&go[0][i][0]!=i){
            cost[0][i][0]=min(cost[0][i][0],cost[0][i][1]+1);
            cost[0][i][1]=min(cost[0][i][1],cost[0][i][0]+1);
        }
    }
//  cerr<<gole(1,6,1).first<<'\n';
    for(int i=1;i<LG;++i){
        for(int j=0;j<n;++j){
            go[i][j][0]=go[i][j][1]=j;
            int lev=l[j]+(1<<i);
			if(l[j]+(1<<i-1)>=l[pref[j]])
				go[i][j][0]=go[i-1][j][0],cost[i][j][0]=cost[i-1][j][0];
			else{
				auto p=gole(j,min(lev,l[pref[j]]),i-1);
				go[i][j][0]=p.first,cost[i][j][0]=p.second;
			}
			if(l[j]+(1<<i-1)>=l[suff[j]])
				go[i][j][1]=go[i-1][j][1],cost[i][j][1]=cost[i-1][j][1];
			else{
				auto q=gori(j,min(lev,l[suff[j]]),i-1);
				go[i][j][1]=q.first,cost[i][j][1]=q.second;
			}
        }
    }
    for(int i=0;i<q;++i){
         int a,b;
		 cin>>a>>b;
         --a,--b;
         if(a>b)swap(a,b);
         int ans=b-a;
         int kek=getmax(a,b+1).first;
         vector<pair<int,int>>as={gori(a,kek)};
         vector<pair<int,int>>bs={gole(b,kek)};
         for(auto a1:as)
             for(auto b1:bs){
                 if(l[a1.first]>=kek&&l[b1.first]>=kek){
                     if(a1.first==b1.first)
                         ans=min(ans,a1.second+b1.second);
                     ans=min(ans,a1.second+b1.second+count_occ(kek,a1.first+1,b1.first)+1);
                 }
             }
         auto a1=gole(a,kek+1);
         auto b1=gori(b,kek+1);
         if(l[a1.first]>kek&&l[b1.first]>kek)
             ans=min(ans,a1.second+b1.second+1);
		 cout<<ans-1<<'\n';
    }
    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...