zoukankan      html  css  js  c++  java
  • 【洛谷P3835】【模板】—可持久化平衡树(可持久化FHQ_Treap)

    传送门

    其实感觉和主席树没什么区别,考虑到TreapTreap期望的树高大约为loglog

    所以每次只会有loglog被改变

    不变的指向儿子就可以了

    注意引用地址符

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
        char ch=getchar();
        int res=0,f=1;
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res*f;
    }
    const int inf=2147483647;
    const int N=500005;
    const int Log=50;
    int son[N*Log][2],val[N*Log],key[N*Log],siz[N*Log];
    int rt[N],n,tot;
    #define lc(u) son[u][0]
    #define rc(u) son[u][1]
    void write(int x){
        if(lc(x))write(lc(x));
        cout<<val[x]<<" ";
        if(rc(x))write(rc(x));
    }
    inline int addnode(int v){
        int u=++tot;
        siz[u]=1,key[u]=rand();
        val[u]=v;return tot;
    }
    inline void pushup(int u){
        siz[u]=siz[lc(u)]+siz[rc(u)]+1;
    }
    inline void copy(int r1,int r2){
        siz[r1]=siz[r2],lc(r1)=lc(r2),rc(r1)=rc(r2),key[r1]=key[r2],val[r1]=val[r2];
    }
    void merge(int &u,int r1,int r2){
        if(!r1||!r2){u=r1+r2;return;}
        if(key[r1]<key[r2]){
            u=++tot,copy(u,r1);
            merge(rc(u),rc(r1),r2);
        }
        else {
            u=++tot,copy(u,r2);
            merge(lc(u),r1,lc(r2));
        }
        pushup(u);
    }
    void split(int u,int v,int &r1,int &r2){
        if(!u){r1=r2=0;return;}
        else{
            if(val[u]<=v){
                r1=++tot,copy(r1,u);
                split(rc(u),v,rc(r1),r2);
                pushup(r1);
            }
            else{
                r2=++tot,copy(r2,u);
                split(lc(u),v,r1,lc(r2));
                pushup(r2);
            }
        }
    }
    inline void insert(int &root,int v){
        int r1,r2,u=addnode(v);
        split(root,v,r1,r2);
        merge(r1,r1,u),merge(root,r1,r2);
    }
    inline void delet(int &root,int v){
        int r1,r2,r3;
        split(root,v,r1,r2);
        split(r1,v-1,r1,r3);
        merge(r3,lc(r3),rc(r3));
        merge(r1,r1,r3);
        merge(root,r1,r2);
    }
    inline int getrk(int root,int k){
        int r1,r2;
        split(root,k-1,r1,r2);
        int res=siz[r1]+1;
        return res;
    }
    inline int kth(int u,int k){
        while(1){
            if(siz[lc(u)]>=k)u=lc(u);
            else if(siz[lc(u)]+1==k)return val[u];
            else k-=siz[lc(u)]+1,u=rc(u);
        }
    }
    inline int pre(int root,int k){
        int r1,r2;
        split(root,k-1,r1,r2);
        if(!r1)return -inf;
        int u=r1;
        while(rc(u))u=rc(u);
        return val[u];
    }
    inline int nxt(int root,int k){
        int r1,r2;
        split(root,k,r1,r2);
        if(!r2)return inf;
        int u=r2;
        while(lc(u))u=lc(u);
        return val[u]; 
    }
    int main(){
        srand(20030224);
        n=read();
        for(int i=1;i<=n;i++){
            int pos=read(),op=read(),x=read();
            rt[i]=rt[pos];
            switch(op){
                case 1:insert(rt[i],x);break;
                case 2:delet(rt[i],x);break;
                case 3:cout<<getrk(rt[i],x)<<'
    ';break;
                case 4:cout<<kth(rt[i],x)<<'
    ';break;
                case 5:cout<<pre(rt[i],x)<<'
    ';break;
                case 6:cout<<nxt(rt[i],x)<<'
    ';break;
            }
        }
    }
    
    
  • 相关阅读:
    常用的Dos命令
    关于CSS3
    数据渲染
    jQuery中的AJAX
    AJAX
    面向对象3
    克隆对象、对象继承
    面向对象2
    面向对象1
    面向对象
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366337.html
Copyright © 2011-2022 走看看