Submission #966387

#TimeUsernameProblemLanguageResultExecution timeMemory
966387tosivanmak밀림 점프 (APIO21_jumps)C++17
100 / 100
1542 ms254880 KiB
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
struct SEG{
    vector<vector<ll> >seg;
    void init(ll n){
        seg.resize(4*n+5);
    }
    void add(ll ul, ll l, ll r, ll val, ll id){
        if(l==r){
            seg[id].pb(val);
        }
        else{
            ll mid=(l+r)>>1;
            seg[id].pb(val);
            if(ul<=mid){
            add(ul,l,mid,val,id*2);
            }
            else{
            add(ul,mid+1,r,val,id*2+1);
            }
        }
    }
    void all(ll l, ll r, ll id){
        sort(seg[id].begin(),seg[id].end());
        if(l==r){
            return;
        }
        else{
            ll mid=(l+r)>>1;
            all(l,mid,id*2),all(mid+1,r,id*2+1);
        }
    }
    ll bs(ll id, ll comp){
        if(seg[id].size()==0){
            return -1e18;
        }
        if(seg[id][0]>comp){
            return -1e18;
        }
        ll l=0,r=seg[id].size()-1;
        while(l<=r){
            if(l==r)break;
            else if(l==r-1){if(seg[id][r]<comp){l=r;}else{r=l;}}
            else{
                ll mid=(l+r)>>1;
                if(seg[id][mid]<comp){
                    l=mid;
                }
                else{
                    r=mid;
                }
            }
        }
        return seg[id][l];
    }
    ll qry(ll ql, ll qr, ll l, ll r, ll comp, ll id){
        if(ql>qr)return -1e18;
        if(l>qr||r<ql){
            return -1e18;
        }
        if(l>=ql&&r<=qr){
            return bs(id,comp);
        }
        ll mid=(l+r)>>1;
        return max(qry(ql,qr,l,mid,comp,id*2),qry(ql,qr,mid+1,r,comp,id*2+1));
    }
}mst;
struct SPARSE{
    vector<vector<pair<ll,ll> > >st;
    vector<ll>arr,lg;
    ll LOG=0;
    void init(ll n){
        st.resize(n+5);
        lg.resize(n+5);
        arr.resize(n+5);
        while((1<<LOG)<=n){
            LOG++;
        }
        for(int i=0;i<n+5;i++){
            st[i].resize(LOG+5);
        }
        lg[1]=0;
        for(int i=2;i<=n;i*=2){
            lg[i]=1;
        }
        for(int i=3;i<=n;i++){
            lg[i]+=lg[i-1];
        }
    }
    void build(ll n){
        for(int i=1;i<=n;i++){
            st[i][0]={arr[i],i};
        }
        for(int j=1;j<=LOG;j++){
            for(int i=1;i<=n;i++){
                if(i+(1<<(j-1))<=n){
                    st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
                }
            }
        }
    }
    pair<ll,ll> qry(ll ql, ll qr){
        if(ql>qr)return {-1e18,-1e18};
        ll rng=lg[qr-ql+1];
        return max(st[ql][rng],st[qr-(1<<rng)+1][rng]);
    }
}st;
ll disc[200005];
ll migi[200005],hidari[200005];
ll ljmp[200005][21],sjmp[200005][21],righ[200005][21];
ll height[200005];
int n;

ll range(ll id, ll l, ll r){
    // cout<<"nigger\n"<<" "<<id<<'\n';
    if(righ[id][20]<l){
        return 3e18;
    }
    // cout<<"fuck nigger\n";
    ll ans=0;
    for(int i=20;i>=0;i--){
        if(righ[id][i]<l){
            id=righ[id][i];
            ans+=(1<<i);
        }
    }
    id=righ[id][0];
    // cout<<id<<'\n';
    ans++;
    if(id>r)return 3e18;
    return ans;
}
ll store;
ll big(ll id, ll par){
    ll ans=0;
    for(int i=20;i>=0;i--){
        if(height[ljmp[id][i]]<par){
            id=ljmp[id][i],ans+=(1<<i);
        }
    }
    store=id;
    return ans;
}
ll small(ll id, ll par){
    ll ans=0;
    for(int i=20;i>=0;i--){
        if(height[sjmp[id][i]]<par){
            id=sjmp[id][i],ans+=(1<<i);
        }
    }
    store=id;
    return ans;
}
ll specific(ll id, ll par, ll par2){
    if(par>par2){
        return 3e18;
    }
    ll one=big(id,par);
    id=store;
    if(height[ljmp[id][0]]<par2){
        return one+2;
    }
    ll bruh=small(id,par);
    return one+bruh+2;
}
void init(int N, std::vector<int> h) {
    n=N;
    st.init(n),mst.init(n);
    for(int i=0;i<n;i++){
        st.arr[i+1]=h[i];
        height[i+1]=h[i];
    }
    for(int i=0;i<n;i++){
        disc[h[i]]=i+1;
    }
    for(int i=1;i<=n;i++){
        migi[i]=-1,hidari[i]=-1;
    }
    for(int i=1;i<=n;i++){
        mst.add(i,1,n,h[i-1],1);
    }
    st.build(n);
    stack<pair<ll,ll> >stt;
    // stt.first=val, stt.second=id;
    for(int i=0;i<n;i++){
        if(stt.empty()){

        }
        else{
            while(stt.size()){
                if(stt.top().first<h[i]){
                    migi[stt.top().second]=i+1;
                    stt.pop();
                }
                else{
                    break;
                }
            }
        }
        stt.push({h[i],i+1});
    }
    while(stt.size())stt.pop();
    for(int i=n-1;i>=0;i--){
        if(stt.empty()){

        }
        else{
            while(stt.size()){
                if(stt.top().first<h[i]){
                    hidari[stt.top().second]=i+1;
                    stt.pop();
                }
                else{
                    break;
                }
            }
        }
        stt.push({h[i],i+1});
    }
    for(int i=1;i<=n;i++){
        if(migi[i]==-1){
            righ[i][0]=i;
        }
        else{
            righ[i][0]=migi[i];
        }
        if(migi[i]==-1&&hidari[i]==-1){
            ljmp[i][0]=sjmp[i][0]=i;
        }
        else{
            if(migi[i]==-1){
                ljmp[i][0]=sjmp[i][0]=hidari[i];
            }
            else if(hidari[i]==-1){
                ljmp[i][0]=sjmp[i][0]=migi[i];
            }
            else{
                if(h[hidari[i]-1]>h[migi[i]-1]){
                    ljmp[i][0]=hidari[i],sjmp[i][0]=migi[i];
                }
                else{
                    ljmp[i][0]=migi[i],sjmp[i][0]=hidari[i];
                }
            }
        }
    }
    for(int j=1;j<=20;j++){
        for(int i=1;i<=n;i++){
          righ[i][j]=righ[righ[i][j-1]][j-1];
          ljmp[i][j]=ljmp[ljmp[i][j-1]][j-1];
          sjmp[i][j]=sjmp[sjmp[i][j-1]][j-1];
        }
    }
    // cout<<righ[14][20]<<'\n';
    mst.all(1,n,1);
}

int minimum_jumps(int a, int b, int c, int d) {
    a++,b++,c++,d++;
    pair<ll,ll>defence=st.qry(c,d);
    ll max_take=defence.first;
    pair<ll,ll>start=st.qry(a,b);
    pair<ll,ll>middle=st.qry(b+1,c-1);
    // if(middle.second>)
    if(b+1>c-1){
        if(height[b]>max_take){
            return -1;
        }
        else{
            return 1;
        }
    }
    ll ans=3e18;
    ll l=start.second+1,r=b;
    while(l<=r){
        if(l==r){
            break;
        }
        else if(l==r-1){
            if(st.qry(l,b).first<max_take){
                r=l;
            }
            else{
                l=r;
            }
        }
        else{
            ll mid=(l+r)>>1;
            if(st.qry(mid,b).first<max_take){
                r=mid;
            }
            else{
                l=mid;
            }
        }
    }
    ll lol=mst.qry(l,b,1,n,max_take,1);
    // cout<<lol<<"\n\n\n";
    if(lol!=-1e18)ans=min(ans,range(disc[lol],c,d));
    // cout<<ans<<'\n';
    if(start.first<max_take){
        ans=min(ans,specific(start.second,middle.first,max_take));
        if(start.first>middle.first){
            ans=min(ans,1LL);
        }
    }
    if(ans>=3e18){
        return -1;
    }
    return ans;
}
// 0 6 8 11
#ifdef LOCAL

int main() {
    freopen("a.out","w",stdout);
  int N, Q;
  assert(2 == scanf("%d %d", &N, &Q));
  std::vector<int> H(N);
  for (int i = 0; i < N; ++i) {
    assert(1 == scanf("%d", &H[i]));
  }
  init(N, H);

  for (int i = 0; i < Q; ++i) {
    int A, B, C, D;
    assert(4 == scanf("%d %d %d %d", &A, &B, &C, &D));
    printf("%d\n", minimum_jumps(A, B, C, D));
  }
  return 0;
}

#endif
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...