[BZOJ3224]普通平衡树

题目大意:
  实现一个数据结构支持下列操作共$n(n\leq100000)$次:
    1.插入一个$x$;
    2.删除一个$x$;
    3.查询$x$的排名;
    4.查询排名为$x$的数;
    5.求$x$的前驱;
    6.求$x$的后继。

思路:
  Splay模板题。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<climits>
 4 inline int getint() {
 5     register char ch;
 6     register bool neg=false;
 7     while(!isdigit(ch=getchar())) if(ch=='-') neg=true;
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return neg?-x:x;
11 }
12 const int N=100001;
13 class SplayTree {
14     private:
15         int val[N],ch[N][2],par[N],size[N],root;
16         int sz,new_node(const int &x) {
17             val[++sz]=x;
18             size[sz]=1;
19             return sz;
20         }
21         void rotate(const int &x) {
22             const int y=par[x];
23             const bool b=x==ch[y][0];
24             size[y]=size[ch[x][b]]+size[ch[y][b]]+1;
25             size[x]=size[ch[x][!b]]+size[y]+1;
26             par[ch[y][!b]=ch[x][b]]=y;
27             if(par[x]=par[y]) ch[par[y]][ch[par[y]][1]==y]=x;
28             par[ch[x][b]=y]=x;
29         }
30         void splay(int x,const int &top) {
31             for(register int y=par[x];y!=top;rotate(x),y=par[x]) {
32                 if(par[y]!=top) rotate((x==ch[y][0])==(y==ch[par[y]][0])?y:x);
33             }
34             if(!top) root=x;
35         }
36     public:
37         void insert(const int &x) {
38             int y=root;
39             while(ch[y][val[y]<x]) y=ch[y][val[y]<x];
40             par[ch[y][val[y]<x]=new_node(x)]=y;
41             splay(sz,0);
42         }
43         void erase(const int &x) {
44             int y=root;
45             while(val[y]!=x) y=ch[y][val[y]<x];
46             splay(y,0);
47             const bool b=!ch[root][1];
48             y=ch[root][1]?:ch[root][0];
49             while(ch[y][b]) y=ch[y][b];
50             splay(y,root);
51             par[root=par[ch[y][b]=ch[root][b]]=y]=0;
52             size[y]=size[ch[y][0]]+size[ch[y][1]]+1;
53         }
54         int order_of_key(const int &x) {
55             int ret=0;
56             for(register int y=root;y;y=ch[y][val[y]<x]) {
57                 if(val[y]<x) ret+=size[ch[y][0]]+1;
58             }
59             return ret+1;
60         }
61         int find_by_order(int x) {
62             for(register int y=root;y;y=ch[y][size[ch[y][0]]<x]) {
63                 if(y!=root&&y==ch[par[y]][1]) x-=size[ch[par[y]][0]]+1;
64                 if(size[ch[y][0]]+1==x) return val[y];
65             }
66         }
67         int prec(const int &x) {
68             int ret;
69             for(register int y=root;y;y=ch[y][val[y]<x]) {
70                 if(val[y]<x) ret=val[y];
71             }
72             return ret;
73         }
74         int succ(const int &x) {
75             int ret;
76             for(register int y=root;y;y=ch[y][val[y]<=x]){
77                 if(val[y]>x) ret=val[y];
78             }
79             return ret;
80         }
81 };
82 SplayTree t;
83 int main() {
84     for(register int i=getint();i;i--) {
85         const int opt=getint(),x=getint();
86         if(opt==1) t.insert(x);
87         if(opt==2) t.erase(x);
88         if(opt==3) printf("%d\n",t.order_of_key(x));
89         if(opt==4) printf("%d\n",t.find_by_order(x));
90         if(opt==5) printf("%d\n",t.prec(x));
91         if(opt==6) printf("%d\n",t.succ(x));
92     }
93     return 0;
94 }

 

posted @ 2018-03-05 11:38  skylee03  阅读(106)  评论(0编辑  收藏  举报