zoukankan      html  css  js  c++  java
  • 树套树模版

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<stack>
    #include<vector>
    #define Tp Treap*
    #define DTp pair<Tp,Tp>
    #define ft first
    #define sc second
    #define MAXN 50000+10
    #define INF 2147483647
    using namespace std;
    struct SBT{
        struct Treap{
            Tp l;Tp r;
            int key,size,fix;
        };
        Tp root;
        int Size(Tp A){
            return (A?A->size:0);
        }
        void upd(Tp A){
            A->size=Size(A->l)+Size(A->r)+1;
        }
        void Print(Tp A,int k){
            if(!A)return;
            Print(A->l,k+1);
            printf("%d,",A->key);
            Print(A->r,k+1);
            if(!k)printf("
    ");
        }
        Tp new_treap(int v){
            Tp ret;ret=new Treap();
            ret->l=ret->r=NULL;
            ret->key=v,ret->size=1,ret->fix=rand();
            return ret;
        }
        Tp Build(int a[],int L,int R){
            vector<int> b;
            stack<Tp> s;
            Tp lst;
            for(int i=L;i<=R;i++)b.push_back(a[i]);
            sort(b.begin(),b.end());
            for(int i=0;i<b.size();i++){
                Tp x=new_treap(b[i]);
                lst=NULL;
                while(!s.empty()&&s.top()->fix>x->fix){
                    upd(s.top());
                    lst=s.top();
                    s.pop();
                }
                if(!s.empty()) s.top()->r=x;
                x->l=lst;
                s.push(x);
            }
            while(!s.empty()){
                upd(s.top());
                lst=s.top();
                s.pop();
            }
            return lst;
        }
        Tp Merge(Tp A,Tp B){
            if(!A)return B;
            if(!B)return A;
            if(A->fix<B->fix){
                A->r=Merge(A->r,B);
                upd(A);
                return A;
            }
            else{
                B->l=Merge(A,B->l);
                upd(B);
                return B;
            }
        }
        DTp Split(Tp A,int k){
            if(!A)return DTp(NULL,NULL);
            DTp y;
            if(Size(A->l)>=k){
                y=Split(A->l,k);
                A->l=y.sc;
                upd(A);
                y.sc=A;
            }
            else{
                y=Split(A->r,k-Size(A->l)-1);
                A->r=y.ft;
                upd(A);
                y.ft=A;
            }
            return y;
        }
        int GetKth(Tp A,int v){
            if(!A)return 0;
            return (v<=A->key?GetKth(A->l,v):GetKth(A->r,v)+Size(A->l)+1);
        }
        int Pre(int v){
            int k=GetKth(root,v);
            if(!k)return -INF; //!!!
            DTp x=Split(root,k-1);
            DTp y=Split(x.sc,1);
            int ans=(y.ft?y.ft->key:-INF);
            root=Merge(x.ft,Merge(y.ft,y.sc));
            return ans;
        }
        int Nxt(int v){
            int k=GetKth(root,v+1);
            DTp x=Split(root,k);
            DTp y=Split(x.sc,1);
            int ans=(y.ft?y.ft->key:INF);
            root=Merge(x.ft,Merge(y.ft,y.sc));
            return ans;
        }
        void Delete(int v){
            int k=GetKth(root,v);
            DTp x=Split(root,k);
            DTp y=Split(x.sc,1);
            root=Merge(x.ft,y.sc);
        }
        void Insert(int v){
            int k=GetKth(root,v);
            DTp x=Split(root,k);
            Tp t=new_treap(v);
            root=Merge(x.ft,Merge(t,x.sc));
        }
    }dat[MAXN<<2];
    int a[MAXN];
    int n,m;
    void build(int k,int L,int R){
        dat[k].root=dat[k].Build(a,L,R-1);
        if(L+1==R)return;
        build(k<<1,L,(L+R)>>1);
        build(k<<1|1,(L+R)>>1,R);
    }
    int rk(int a,int b,int k,int L,int R,int x){// ret=ans-1
        int mid=(L+R)>>1;
        if(a<=L&&R<=b)return dat[k].GetKth(dat[k].root,x);
        if(b<=mid)return rk(a,b,k<<1,L,mid,x);
        if(a>=mid)return rk(a,b,k<<1|1,mid,R,x);
        return rk(a,b,k<<1,L,mid,x)+rk(a,b,k<<1|1,mid,R,x);
    }
    int getx(int a,int b,int k){
        int L=0,R=100000000;
        while(R-L>1){
            int mid=(L+R)>>1;
            int k1=rk(a,b+1,1,1,n+1,mid)+1;
            int k2=rk(a,b+1,1,1,n+1,mid+1);
            if(k1<=k&&k<=k2)return mid;
            if(k2<k){
                L=mid;
            }
            else if(k1>k){
                R=mid;
            }
        }
        int k1=rk(a,b+1,1,1,n+1,L);k1++;
        int k2=rk(a,b+1,1,1,n+1,L+1);
        if(k1<=k&&k<=k2)return L;
        else return R;
    }
    int pre(int a,int b,int k,int L,int R,int x){
        int mid=(L+R)>>1;
        if(a<=L&&R<=b)return dat[k].Pre(x);
        if(b<=mid)return pre(a,b,k<<1,L,mid,x);
        if(a>=mid)return pre(a,b,k<<1|1,mid,R,x);
        return max(pre(a,b,k<<1,L,mid,x),pre(a,b,k<<1|1,mid,R,x));
    }
    int nxt(int a,int b,int k,int L,int R,int x){
        int mid=(L+R)>>1;
        if(a<=L&&R<=b)return dat[k].Nxt(x);
        if(b<=mid)return nxt(a,b,k<<1,L,mid,x);
        if(a>=mid)return nxt(a,b,k<<1|1,mid,R,x);
        return min(nxt(a,b,k<<1,L,mid,x),nxt(a,b,k<<1|1,mid,R,x));
    }
    void update(int a,int k,int L,int R,int x,int y){
        dat[k].Delete(x);
        dat[k].Insert(y);
        if(L+1==R)return;
        int mid=(L+R)>>1;
        if(a<mid)update(a,k<<1,L,mid,x,y);
        else update(a,k<<1|1,mid,R,x,y);
    }
    void init(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        build(1,1,n+1);
    }
    void AskRk(){
        int L,R,x;
        scanf("%d%d%d",&L,&R,&x);
        printf("%d
    ",rk(L,R+1,1,1,n+1,x)+1);
    }
    void AskNum(){
        int L,R,k;
        scanf("%d%d%d",&L,&R,&k);
        printf("%d
    ",getx(L,R,k));
    }
    void AskUpd(){
        int pos,x;
        scanf("%d%d",&pos,&x);
        update(pos,1,1,n+1,a[pos],x);
        a[pos]=x;
    }
    void AskPre(){
        int L,R,x;
        scanf("%d%d%d",&L,&R,&x);
        int ans=pre(L,R+1,1,1,n+1,x);
        printf("%d
    ",(ans<x?ans:-INF));
    }
    void AskNxt(){
        int L,R,x;
        scanf("%d%d%d",&L,&R,&x);
        int ans=nxt(L,R+1,1,1,n+1,x);
        printf("%d
    ",(ans>x?ans:INF));
    }
    void solve(){
        int opt;
        while(m--){
            scanf("%d",&opt);
            switch(opt){
                case 1:AskRk();break;
                case 2:AskNum();break;
                case 3:AskUpd();break;
                case 4:AskPre();break;
                case 5:AskNxt();
            }
        }
    }
    int main()
    {
    //    freopen("data.in","r",stdin);
    //    freopen("my.out","w",stdout);
        init();
        solve();
        return 0;
    }
  • 相关阅读:
    Android 打开相册拍照选择多张图片显示
    Mac 打开、编辑 .bash_profile 文件
    Ionic app IOS 在Xcode 模拟运行 真机调试
    android studio 把 ionic 打包时修改应用名称、修改应用图标、修改启动画面,升级打包
    Android studio 运行打包 Ionic 项目
    ionic4 路由跳转、ionic4 路由跳转传值 NavController 返回上一页 、NavController 回到根
    Ionic4.x ion-refresher 下拉更新
    Ionic4.x ion-infinite-scroll 上拉分页加载更多
    Ionic4.x ion-infinite-scroll 上拉分页加载更多
    Ionic4.x Modal模态对话框以及 Modal 传值
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8128131.html
Copyright © 2011-2022 走看看