Treap,替罪羊树,splay。跑得不慢,代码在不影响版面的前提下基本已经缩到极限了,不知道还能不能更短。

其实我还会写AVL树,只不过太长懒得写了。反正Treap和替罪羊树跑得也挺快,用用这俩就够了。

话说Treap和替罪羊树都是重量平衡树来着……这倒是方便我了,不过写动态标号的时候到底该写哪个呢……这是个问题……

 

Treap(普通平衡树):

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 struct node{
  6     static inline int randint(){
  7         static int a=1213857,b=123542441,x=741542853,p=998244353;
  8         x=a*x+b;x%=p;
  9         return (x<0)?(x+=p):x;
 10     }
 11     int data,size,p;
 12     node *ch[2];
 13     node(int d):data(d),size(1),p(randint()){}
 14     void refresh(){size=ch[0]->size+ch[1]->size+1;}
 15     int cmp(int x){return x==data?-1:x>data;}
 16 }*null=new node(-1),*root=null;
 17 void insert(int,node*&);
 18 void erase(int,node*&);
 19 int order(int,node*);
 20 node *kth(int,node*);
 21 node *pred(int,node*);
 22 node *succ(int,node*);
 23 void rot(node*&,int);
 24 int n,d,x;
 25 int main(){
 26     null->size=0;
 27     null->ch[0]=null->ch[1]=null;
 28     scanf("%d",&n);
 29     while(n--){
 30         scanf("%d%d",&d,&x);
 31         if(d==1)insert(x,root);
 32         else if(d==2)erase(x,root);
 33         else if(d==3)printf("%d\n",order(x,root));
 34         else if(d==4)printf("%d\n",kth(x,root)->data);
 35         else if(d==5)printf("%d\n",pred(x,root)->data);
 36         else printf("%d\n",succ(x,root)->data);
 37     }
 38     return 0;
 39 }
 40 void insert(int x,node *&rt){
 41     if(rt==null){
 42         rt=new node(x);
 43         rt->ch[0]=rt->ch[1]=null;
 44         return;
 45     }
 46     int d=abs(rt->cmp(x));
 47     insert(x,rt->ch[d]);
 48     rt->refresh();
 49     if(rt->ch[d]->p<rt->p)rot(rt,d^1);
 50 }
 51 void erase(int x,node *&rt){
 52     int d=rt->cmp(x);
 53     if(d==-1){
 54         if(rt->ch[0]!=null&&rt->ch[1]!=null){
 55             d=rt->ch[0]->p<=rt->ch[1]->p;
 56             rot(rt,d);
 57             erase(x,rt->ch[d]);
 58         }
 59         else{
 60             node *y=rt->ch[0]!=null?rt->ch[0]:rt->ch[1];
 61             delete rt;
 62             rt=y;
 63         }
 64     }
 65     else erase(x,rt->ch[d]);
 66     if(rt!=null)rt->refresh();
 67 }
 68 int order(int x,node *rt){
 69     int ans=1,d;
 70     while(rt!=null){
 71         if((d=x>rt->data))ans+=rt->ch[0]->size+1;
 72         rt=rt->ch[d];
 73     }
 74     return ans;
 75 }
 76 node *kth(int k,node *rt){
 77     int d;
 78     while(rt!=null){
 79         if(k==rt->ch[0]->size+1)return rt;
 80         if((d=k>rt->ch[0]->size+1))k-=rt->ch[0]->size+1;
 81         rt=rt->ch[d];
 82     }
 83     return null;
 84 }
 85 node *pred(int x,node *rt){
 86     node *y=null;
 87     int d;
 88     while(rt!=null){
 89         if((d=x>rt->data))y=rt;
 90         rt=rt->ch[d];
 91     }
 92     return y;
 93 }
 94 node *succ(int x,node *rt){
 95     node *y=null;
 96     int d;
 97     while(rt!=null){
 98         if((d=x<rt->data))y=rt;
 99         rt=rt->ch[d^1];
100     }
101     return y;
102 }
103 void rot(node *&x,int d){
104     node *y=x->ch[d^1];
105     x->ch[d^1]=y->ch[d];
106     y->ch[d]=x;
107     x->refresh();
108     (x=y)->refresh();
109 }
View Code

相关文章:

  • 2021-11-23
  • 2022-01-16
  • 2021-10-06
  • 2021-05-18
  • 2022-12-23
  • 2021-06-04
  • 2021-08-02
猜你喜欢
  • 2021-07-17
  • 2021-07-13
  • 2022-01-13
  • 2021-08-11
  • 2022-01-26
  • 2022-12-23
  • 2021-06-02
相关资源
相似解决方案