【洛谷P3835】【模板】—可持久化平衡树(可持久化FHQ_Treap)

传送门

其实感觉和主席树没什么区别,考虑到 T r e a p Treap 期望的树高大约为 l o g log

所以每次只会有 l o g log 被改变

不变的指向儿子就可以了

注意引用地址符

#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)<<'\n';break;
            case 4:cout<<kth(rt[i],x)<<'\n';break;
            case 5:cout<<pre(rt[i],x)<<'\n';break;
            case 6:cout<<nxt(rt[i],x)<<'\n';break;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42555009/article/details/86626932