Submission #1351613

#TimeUsernameProblemLanguageResultExecution timeMemory
1351613WarinchaiSpecijacija (COCI20_specijacija)C++20
110 / 110
2892 ms348952 KiB
#include<bits/stdc++.h>
#define int long long
using namespace std;

int a[200005];
int n,q,t;

struct node{
    node *l,*r;
    int info;
    int lz=0;
    node(int x=0){
        info=x;
        l=r=NULL;
    }
};
typedef node* pnode;

struct psegtree{
    pnode rt[200005];
    void push(int st,int en,pnode &x){
        if(x->lz==0)return;
        x->info+=x->lz;
        if(st!=en){
            x->l->lz+=x->lz;
            x->r->lz+=x->lz;
        }
        x->lz=0;
    }
    void build(int st,int en,pnode &x){
        x=new node();
        if(st==en){
            return void(x->info=st);
        }
        int m=(st+en)/2;
        build(st,m,x->l);
        build(m+1,en,x->r);
        x->info=max(x->l->info,x->r->info);
    }
    void upd(int st,int en,pnode x,pnode &y,int l,int r,int val){
        //cerr<<"try:"<<st<<" "<<en<<"\n";
        y=new node(*x);
        if(st>r||en<l)return;
        if(st>=l&&en<=r){
            y->lz+=val;
            return;
        }
        int m=(st+en)/2;
        upd(st,m,x->l,y->l,l,r,val);
        upd(m+1,en,x->r,y->r,l,r,val);
        y->info=max(y->l->info+y->l->lz,y->r->info+y->r->lz);
    }
    int fval(int st,int en,pnode &x,int pos,int sum=0){
        int m=(st+en)/2;
        sum+=x->lz;
        if(st==en)return x->info+sum;
        if(pos<=m)return fval(st,m,x->l,pos,sum);
        else return fval(m+1,en,x->r,pos,sum);
    }
    int f(int st,int en,pnode &x,int val){
        val-=x->lz;
        if(st==en)return st;
        int m=(st+en)/2;
        if(x->l->info+x->l->lz<=val)return f(m+1,en,x->r,val);
        else return f(st,m,x->l,val);
    }
}tr;

pair<int,int> lca(int x,int lx,int y,int ly){
    if(lx<ly){
        swap(x,y);
        swap(lx,ly);
    }
    for(int i=19;i>=0;i--){
        if(lx-(1<<i)>=ly)lx-=(1<<i);
    }
    //if(p[lx][x]==p[ly][y])return {x,lx};
    if(tr.fval(1,n+1,tr.rt[lx],x)==tr.fval(1,n+1,tr.rt[ly],y))return {x,lx};
    for(int i=19;i>=0;i--){
        if(lx-(1<<i)>0){
            //p[lx-(1<<i)][x]!=p[ly-(1<<i)][y]
            if(tr.fval(1,n+1,tr.rt[lx-(1<<i)],x)!=tr.fval(1,n+1,tr.rt[ly-(1<<i)],y)){
                lx=lx-(1<<i),ly=ly-(1<<i);
            }
        }
    }
    return make_pair(x,lx-1);
}

int32_t main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>q>>t;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    //cerr<<"work\n";
    tr.build(1,n+1,tr.rt[n+1]);
    for(int i=n;i>=1;i--){
        int x=a[i]-(i*(i-1)/2);
        //cerr<<"i:"<<i<<" "<<x<<"\n";
        //int pos=upper_bound(p[i+1]+1,p[i+1]+1+n,x)-p[i+1];
        int pos=tr.f(1,n+1,tr.rt[i+1],x);
        //cerr<<"pos:"<<pos<<"\n";
        //for(int j=1;j<=n+1;j++)p[i][j]=p[i+1][j];
        //for(int j=pos;j<=n+1;j++)p[i][j]--;
        tr.upd(1,n+1,tr.rt[i+1],tr.rt[i],pos,n+1,-1);
        //cerr<<"upd\n";
        /*for(int k=i;k<=n+1;k++){
            for(int j=1;j<=n+1;j++){
                cerr<<tr.fval(1,n+1,tr.rt[k],j)<<" ";
            }
            cerr<<"\n";
        }
        cerr<<"\n";*/
    }
    /*cerr<<"\n";
    for(int i=1;i<=n+1;i++){
        for(int j=1;j<=n+1;j++){
            cerr<<tr.fval(1,n+1,tr.rt[i],j)<<" ";
        }
        cerr<<"\n";
    }
    cerr<<"work\n";*/
    int prv=0;
    int md=(n+1)*(n+2)/2;
    vector<int>st;
    for(int i=1;i<=n+1;i++){
        st.push_back(i*(i-1)/2+1);
    }
    for(int i=0;i<q;i++){
        int x,y;cin>>x>>y;
        x=(x-1+t*prv)%(md)+1;
        y=(y-1+t*prv)%(md)+1;
        int lx=upper_bound(st.begin(),st.end(),x)-st.begin();
        int ly=upper_bound(st.begin(),st.end(),y)-st.begin();
        x-=(lx*(lx-1)/2);
        y-=(ly*(ly-1)/2);
        /*
        x=lower_bound(p[lx]+1,p[lx]+n+2,x)-p[lx];
        y=lower_bound(p[ly]+1,p[ly]+n+2,y)-p[ly];*/
        x=tr.f(1,n+1,tr.rt[lx],x-1);
        y=tr.f(1,n+1,tr.rt[ly],y-1);
        auto ans=lca(x,lx,y,ly);
        //int rans=p[ans.second][ans.first]+ans.second*(ans.second-1)/2;
        int rans=tr.fval(1,n+1,tr.rt[ans.second],ans.first)+ans.second*(ans.second-1)/2;
        cout<<rans<<"\n";
        prv=rans;
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...