P3369 【模板】普通平衡树 treap树旋转版

 

#include<bits/stdc++.h>
#define INF INT_MAX
using namespace std;
const int maxn=100010;
int sum=0,R=0;
int sz[maxn],v[maxn],num[maxn],rd[maxn],son[maxn][2];
//更新p子树的大小 
void pushup(int p){
     sz[p]=sz[son[p][0]]+sz[son[p][1]]+num[p];
}
//旋转 
void rot(int&p,int d){
     int k=son[p][d^1];
     son[p][d^1]=son[k][d];
     son[k][d]=p;
     pushup(p);
     pushup(k);
     p=k;
}
//插入
void ins(int &p,int x){
     if (!p){
        p=++sum;
        sz[p]=num[p]=1;
        v[p]=x;
        rd[p]=rand();
        return ;
     }
     if(v[p]==x){
        num[p]++;
        sz[p]++;
        return ;
     }
     int d=(x>v[p]);//右子树
     ins(son[p][d],x);
     if (rd[p]<rd[son[p][d]]) rot(p,d^1);
     pushup(p);
}
//删除 
void del(int &p,int x){
     if(!p) return ;
     if(x<v[p]) del(son[p][0],x);
     else if(x>v[p]) del(son[p][1],x);
     else {
          if(!son[p][0]&&!son[p][1]){
              num[p]--;sz[p]--;
              if (!num[p]) p=0;
          }
          else if(!son[p][1]){
               rot(p,1);
               del(son[p][1],x);
          }
          else if(!son[p][0]){
               rot(p,0);
               del(son[p][0],x);
          }
          else{
               int d=(rd[son[p][0]]>rd[son[p][1]]);
               rot(p,d);
               del(son[p][d],x);
          }
     }
     pushup(p);
}
//x的排名 
int get_rank(int p,int x){
    if(!p) return 0;
    if(v[p]==x) return sz[son[p][0]]+1;
    if(v[p]<x) return sz[son[p][0]]+num[p]+get_rank(son[p][1],x);
    if(v[p]>x) return get_rank(son[p][0],x);
}
//排名x的值
int func_find(int p,int x){
    if(!p) return 0;
    if(sz[son[p][0]]>=x) return func_find(son[p][0],x);
    else if(sz[son[p][0]]+num[p]<x)
         return func_find(son[p][1],x-num[p]-sz[son[p][0]]);
    else return v[p];
}
//前驱
int pre(int p,int x){
    if (!p) return -INF;
    if (v[p]>=x) return pre(son[p][0],x);
    else return max(v[p],pre(son[p][1],x));
}
//后继
int suc(int p,int x){
    if (!p) return INF;
    if(v[p]<=x) return suc(son[p][1],x);
    else return min(v[p],suc(son[p][0],x));
}
int main()
{
	int n,op,x;
	cin>>n;
	while(n--)
	{
		cin>>op>>x;
		if (op==1) ins(R,x);
		else if(op==2) del(R,x);
		else if(op==3) cout<<get_rank(R,x)<<endl;
		else if(op==4) cout<<func_find(R,x)<<endl;
		else if(op==5) cout<<pre(R,x)<<endl;
		else if(op==6) cout<<suc(R,x)<<endl; 
	}
}

  

posted @ 2022-03-17 23:14  心悟&&星际  阅读(22)  评论(0)    收藏  举报