BZOJ 3224 普通平衡树

Description

您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)

Input

第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

Output

对于操作3,4,5,6每行输出一个数,表示对应答案

Sample Input

10
1 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598

Sample Output

106465
84185
492737

HINT

 

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

 

Source

 

 平衡树裸题,splay大法好。
  1 #include<queue>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 using namespace std;
  5 
  6 #define maxn 100010
  7 const int inf = 1 << 30;
  8 queue <int> team;
  9 struct TREE
 10 {
 11     int ch[maxn][2],fa[maxn],cnt,root;
 12     int key[maxn],size[maxn],t[maxn];
 13     
 14     inline int newnode()
 15     {
 16         if (team.empty()) return ++cnt;
 17         int ret = team.front(); team.pop();
 18         return ret;
 19     }
 20 
 21     inline TREE()
 22     {
 23         root = newnode();
 24         key[root] = -inf; ++t[root];
 25         updata(root);
 26         add(inf);
 27     }
 28 
 29     inline int find(int rank,int have,int now)
 30     {
 31         if (have+size[ch[now][0]]<rank&&have+size[ch[now][0]]+t[now]>=rank) return now;
 32         if (have+size[ch[now][0]]+t[now]<rank) return find(rank,have+size[ch[now][0]]+t[now],ch[now][1]);
 33         else return find(rank,have,ch[now][0]);
 34     }
 35     
 36     inline void updata(int now) { size[now] = size[ch[now][0]] + size[ch[now][1]] + t[now]; }
 37 
 38     inline void rotate(int x)
 39     {
 40         int y = fa[x],z = fa[y],l = ch[y][0] != x,r = l ^ 1;
 41         if (z != 0) ch[z][ch[z][0] != y] = x;
 42         fa[x] = z; fa[y] = x; fa[ch[x][r]] = y;
 43         ch[y][l] = ch[x][r]; ch[x][r] = y;
 44         updata(y); updata(x);
 45     }
 46     
 47     inline void splay(int x,int aim)
 48     {
 49         int p = fa[aim];
 50         while (fa[x] != p)
 51         {
 52             int y = fa[x],z = fa[y];
 53             if (z != p)
 54             {
 55                 if ((ch[z][0] == y)^(ch[y][0] == x)) rotate(x);
 56                 else rotate(y);
 57             }
 58             rotate(x);
 59         }
 60         if (aim == root) root = x;
 61     }
 62 
 63     inline int search(int x)
 64     {
 65         int now = root;
 66         while (now)
 67         {
 68             if (key[now] == x) break;
 69             now = ch[now][x > key[now]];
 70         }
 71         return now;
 72     }
 73 
 74     inline void add(int x)
 75     {
 76         int now = root,pre = 0;
 77         while (now)
 78         {
 79             pre = now;
 80             now = ch[now][x > key[now]];
 81         }
 82         now = newnode();
 83         fa[now] = pre; ch[pre][x > key[pre]] = now;
 84         key[now] = x; ++t[now];
 85         pre = now;
 86         while (now)
 87         {
 88             updata(now);
 89             now = fa[now];
 90         }
 91         splay(pre,root);
 92     }
 93 
 94     inline int qrank(int x)
 95     {
 96         int now = root,ret = 0;
 97         while (key[now] != x)
 98         {
 99             if (x < key[now]) now = ch[now][0];
100             else ret += size[ch[now][0]] + t[now],now = ch[now][1];
101         }
102         return ret + size[ch[now][0]] + 1;
103     }
104     
105     inline void insert(int x)
106     {
107         int p = search(x);
108         if (p)
109         {
110             splay(p,root);
111             ++t[p];
112             updata(p);
113         }
114         else add(x);
115     }
116 
117     inline void del(int x)
118     {
119         int now = search(x),k = qrank(x);
120         int p = find(k-1,0,root),q = find(k + t[now],0,root);
121         splay(p,root);
122         splay(q,ch[p][1]);
123         if (--t[now])
124         {
125             updata(now);
126             updata(q);
127             updata(p);
128         }
129         else
130         {
131             ch[q][0] = 0; fa[now] = 0;
132             updata(q);
133             updata(p);
134             team.push(now);
135         }
136     }
137 
138     inline int ask(int x,int sign)
139     {
140         int now = root,ret;
141         while (now)
142         {
143             if (sign)
144             {
145                 if (key[now] > x)
146                     ret = now,now = ch[now][0];
147                 else now = ch[now][1];
148             }
149             else
150             {
151                 if (key[now] < x)
152                     ret = now,now = ch[now][1];
153                 else now = ch[now][0];
154             }
155         }
156         return key[ret];
157     }
158 }tree;
159 
160 inline int read()
161 {
162     int x=0,f=1;char ch=getchar();
163     while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
164     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
165     return x*f;
166 }
167 
168 int main()
169 {
170     freopen("3224.in","r",stdin);
171     freopen("3224.out","w",stdout);
172     int T = read();
173     while (T--)
174     {
175         int opt = read();
176         if (opt == 1) tree.insert(read());
177         else if (opt == 2) tree.del(read());
178         else if (opt == 3) printf("%d\n",tree.qrank(read())-1);
179         else if (opt == 4) printf("%d\n",tree.key[tree.find(read()+1,0,tree.root)]);
180         else if (opt == 5) printf("%d\n",tree.ask(read(),0));
181         else printf("%d\n",tree.ask(read(),1));
182     }
183     fclose(stdin); fclose(stdout);
184     return 0;
185 }
View Code

 

posted @ 2015-02-16 19:52  lmxyy  阅读(180)  评论(0编辑  收藏  举报