可持久化平衡树求条
查看原帖
可持久化平衡树求条
322792
Alea楼主2023/9/19 10:40
#include <iostream>
using namespace std;
const int SIZE=5e5+10;
int val[SIZE*50],ch[SIZE*50][2],rnd[SIZE*50],siz[SIZE*50],tot,root[SIZE*50];
void pushup(int cur){
    siz[cur]=siz[ch[cur][0]]+siz[ch[cur][1]]+1;
}
int create(int lue=0){
    ++tot;
    val[tot]=lue;
    siz[tot]=1;
    rnd[tot]=rand();
    ch[tot][0]=ch[tot][1]=0;
    return tot;
}
void copy(int dst,int src){
    val[dst]=src;
    ch[dst][0]=ch[src][0],ch[dst][1]=ch[src][1];
    siz[dst]=siz[src];
    rnd[dst]=rnd[src];
}
int merge(int lcur,int rcur){
    if(lcur==0||rcur==0) return lcur+rcur;
    int cur=create();
    if(rnd[lcur]<rnd[rcur]){
        copy(cur,lcur);
        ch[cur][1]=merge(ch[cur][1],rcur);
    }else{
        copy(cur,rcur);
        ch[cur][0]=merge(lcur,ch[cur][0]);
    }
    pushup(cur);
    return cur;
}
void split(int cur,int lue,int &lcur,int &rcur){
    if(cur==0) lcur=rcur=0;
    else{
        if(val[cur]<=lue){
            lcur=create();
            copy(lcur,cur);
            split(ch[lcur][1],lue,ch[lcur][1],rcur);
            pushup(lcur);
        }else{
            rcur=create();
            copy(rcur,cur);
            split(ch[rcur][0],lue,lcur,ch[rcur][0]);
            pushup(rcur);
        }
    }
}
void insert(int lue,int ver){
    int l,r;
    split(root[ver],lue,l,r);
    root[ver]=merge(merge(l,create(lue)),r);
}
void remove(int lue,int ver){
    int l,r,m;
    split(root[ver],lue,l,r);
    split(l,lue-1,l,m);
    m=merge(ch[m][0],ch[m][1]);
    root[ver]=merge(merge(l,m),r);
}
int elernk(int lue,int ver){
    int l,r,ans;
    split(root[ver],lue-1,l,r);
    ans=siz[l]+1;
    root[ver]=merge(l,r);
    return ans;
}
int kthele(int kth,int ver){
    int cur=root[ver];
    while(true){
        if(kth<=siz[ch[cur][0]]) cur=ch[cur][0];
        else{
            if(ch[cur][0]!=0) kth-=siz[ch[cur][0]];
            if((--kth)==0) return cur;
            cur=ch[cur][1];
        }
    }
}
int preele(int lue,int ver){
    int l,r,ans;
    split(root[ver],lue-1,l,r);
    if(l==0) return (1<<31)+1;
    ans=val[kthele(l,siz[l])];
    root[ver]=merge(l,r);
    return ans;
}
int subele(int lue,int ver){
    int l,r,ans;
    split(root[ver],lue,l,r);
    if(r==0) return (1<<31)-1;
    ans=val[kthele(r,1)];
    root[ver]=merge(l,r);
    return ans;
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        int v,o,x;
        cin>>v>>o>>x;
        root[i]=root[v];
        if(o==1) insert(x,i);
        else if(o==2) remove(x,i);
        else if(o==3) cout<<elernk(x,i)<<endl;
        else if(o==4) cout<<val[kthele(x,i)]<<endl;
        else if(o==5) cout<<preele(x,i)<<endl;
        else cout<<subele(x,i)<<endl;
    }
    return 0;
}
2023/9/19 10:40
加载中...