【模板】fhq-Treap

传送门

  1. 插入 xx 数
  2. 删除 xx 数(若有多个相同的数,因只删除一个)
  3. 查询 xx 数的排名(排名定义为比当前数小的数的个数 +1+1 )
  4. 查询排名为 xx 的数
  5. 求 xx 的前驱(前驱定义为小于 xx,且最大的数)
  6. 求 xx 的后继(后继定义为大于 xx,且最小的数)
#include<iostream>
#include<cstdio>
#define INF 0x3f3f3f3f
using namespace std;
int n,op,x,c_x,c_y;
int root,t[100050][2],Size[100050],val[100050],td;
unsigned long long zz=998244353; 
int Rank(){
    return zz=(int)(zz*1000000007);
}
void update(int x) { 
    Size[x]=Size[t[x][0]]+Size[t[x][1]]+1;
}
void split(int x,int k) {
    if(!x){
        c_x=c_y=0;
        return; 
    }
    if(Size[t[x][0]]<k){
        split(t[x][1],k-(Size[t[x][0]]+1));
        t[x][1]=c_x;
        c_x=x;
    }
    else{
        split(t[x][0],k);
        t[x][0]=c_y;
        c_y=x;
    }
    update(x);
}
int merge(int a, int b) {
    if(a==0||b==0) return a+b;
    if(Rank()%(Size[a]+Size[b])<Size[a]) {
        t[a][1]=merge(t[a][1],b); 
        update(a); 
        return a;
    } 
    else{
        t[b][0]=merge(a,t[b][0]); 
        update(b); 
        return b;
    }
}
int val_rank(int x,int k) {
    if(!x) return 0;
    if(val[x]>=k) return val_rank(t[x][0],k);
    return val_rank(t[x][1],k)+Size[t[x][0]]+1;
}
void ins(int k) {
    val[++td]=k; 
    Size[td]=1;
    split(root,val_rank(root,k));
    root=merge(c_x,td); 
    root=merge(root,c_y);
}
void del(int k) {
    split(root,val_rank(root,k)); 
    root=c_x;
    split(c_y,1); 
    root=merge(root,c_y);
}
int rank_val(int x,int k) {
    if(Size[t[x][0]]>=k) return rank_val(t[x][0],k);
    if(Size[t[x][0]]+1==k) return val[x];
    return rank_val(t[x][1],k-Size[t[x][0]]-1);
}
int pre(int x,int k) {
    if(!x) return INF;
    if(val[x]<k) {
        int p=pre(t[x][1],k);
        if(p==INF) return val[x];
        return p;
    }
    return pre(t[x][0],k);
}
int nxt(int x,int k) {
    if(!x) return INF;
    if(val[x]>k) {
        int p=nxt(t[x][0],k);
        if(p==INF) return val[x];
        return p;
    }
    return nxt(t[x][1],k);
}
int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        scanf("%d%d",&op,&x);
        if(op==1) ins(x);
        if(op==2) del(x);
        if(op==3) printf("%d\n",val_rank(root,x)+1);
        if(op==4) printf("%d\n",rank_val(root,x));
        if(op==5) printf("%d\n",pre(root,x));
        if(op==6) printf("%d\n",nxt(root,x));
    }
}

 

posted @ 2021-08-06 21:11  latent_Lin  阅读(44)  评论(0)    收藏  举报