fhq treap

fhq 平衡树

这里的支持的是 \(ins,del,pre,nxt,kth,rank\)

#include <bits/stdc++.h>
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define mod 23333
#define ll long long
#define N 10000005
using namespace std;
inline int rd(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
struct Node{
    int l,r;
    int val,key,siz;//数值,键值,子树大小
}tr[N];
int cnt,root;
inline int newnode(int x){
    tr[++cnt].val=x;
    tr[cnt].siz=1;
    tr[cnt].key=rand();
    return cnt;
}
inline void push_up(int p){
    tr[p].siz=tr[tr[p].l].siz+tr[tr[p].r].siz+1;
}
int n,m,last;
void spilt(int now,int val,int &x,int &y){//理解x,y是两颗子树的两个插入接口
    if(!now)x=y=0;
    else {
        if(tr[now].val<=val){
            x=now;
            spilt(tr[now].r,val,tr[now].r,y);
        }
        else {
            y=now;
            spilt(tr[now].l,val,x,tr[now].l);
        }
        push_up(now);
    } 
} 
int merge(int x,int y){
    if(!x||!y)return x+y;
    if(tr[x].key>tr[y].key){
        tr[x].r=merge(tr[x].r,y);
        push_up(x);
        return x;
    }
    else {
        tr[y].l=merge(x,tr[y].l);
        push_up(y);
        return y;
    }
}
int x, y, z;
inline void ins(int val){
    spilt(root,val,x,y);
    root=merge(merge(x,newnode(val)),y);
}
inline void del(int val){
    spilt(root,val,x,z);
    spilt(x,val-1,x,y);
    y=merge(tr[y].l,tr[y].r);
    root=merge(merge(x,y),z);
}
inline void getrank(int val){
    spilt(root,val-1,x,y);
    cout<<tr[x].siz+1<<endl;
    root=merge(x,y);
}
inline void getnum(int rank){
    int now=root;
    while(now){
        if(tr[tr[now].l].siz+1==rank)break;
        else if(tr[tr[now].l].siz>=rank)
            now=tr[now].l;
        else {
            rank-=tr[tr[now].l].siz+1;
            now=tr[now].r;
        }
    }
    cout<<tr[now].val<<endl;
}
inline void pre(int val){
    spilt(root,val-1,x,y);
    int now=x;
    while(tr[now].r)
        now=tr[now].r;
    cout<<tr[now].val<<endl;
    root=merge(x,y);
}
inline void lst(int val){
    spilt(root,val,x,y);
    int now=y;
    while(tr[now].l)
        now=tr[now].l;
    cout<<tr[now].val<<endl;
    root=merge(x,y);
}
signed main() {
    n=rd();
    F(i,1,n){
        int op=rd(),xx=rd();
        if(op==1)ins(xx);
        else if(op==2)del(xx);
        else if(op==3)getrank(xx);
        else if(op==4)getnum(xx);
        else if(op==5)pre(xx);
        else lst(xx);
    }
    return 0;
}

posted @ 2023-09-09 17:09  ussumer  阅读(35)  评论(0)    收藏  举报