题目地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
题目大意:维护平衡树的6个操作。
算法讨论:
平衡树裸题。
具体就不多说了,我用的是Treap。
Code:
/*
* Problem:3224
* Author:PYC
*/
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define maxn 1000000
#define oo 1000000000
using namespace std;
int m,tot,root;
struct node{int key,val,aux,l,r,ll,rr;}tree[maxn];
inline void zig(int &root){
int t=tree[root].l;
tree[root].l=tree[t].r;
tree[root].ll=tree[t].rr;
tree[t].r=root;
tree[t].rr=tree[t].rr+tree[root].rr+tree[root].val;
root=t;
}
inline void zag(int &root){
int t=tree[root].r;
tree[root].r=tree[t].l;
tree[root].rr=tree[t].ll;
tree[t].l=root;
tree[t].ll=tree[t].ll+tree[root].ll+tree[root].val;
root=t;
}
void insert(int &root,int y){
if (!root){
root=++tot;
tree[root].key=y;
tree[root].val=1;
tree[root].aux=rand();
return;
}
if (y==tree[root].key){tree[root].val++;return;}
if (y<tree[root].key){
insert(tree[root].l,y);
tree[root].ll++;
if (tree[root].aux>tree[tree[root].l].aux) zig(root);
return;
}
if (y>tree[root].key){
insert(tree[root].r,y);
tree[root].rr++;
if (tree[root].aux>tree[tree[root].r].aux) zag(root);
return;
}
}
void del(int &root,int y){
if (!root) return;
if (y==tree[root].key){
if (tree[root].val>1){tree[root].val--;return;}
if (!tree[root].l || !tree[root].r){
if (!tree[root].l){root=tree[root].r;return;}
if (!tree[root].r){root=tree[root].l;return;}
}
if (tree[tree[root].l].aux<tree[tree[root].r].aux){
zig(root);
del(tree[root].r,y);
tree[root].rr--;
return;
}
else{
zag(root);
del(tree[root].l,y);
tree[root].ll--;
return;
}
}
if (y<tree[root].key){
del(tree[root].l,y);
tree[root].ll--;
return;
}
if (y>tree[root].key){
del(tree[root].r,y);
tree[root].rr--;
return;
}
}
int rank(int &root,int y){
if (!root) return 0;
if (y==tree[root].key) return tree[root].ll+1;
if (y<tree[root].key) return rank(tree[root].l,y);
if (y>tree[root].key) return tree[root].ll+tree[root].val+rank(tree[root].r,y);
}
int kth(int &root,int y){
if (!root) return 0;
if (y<=tree[root].ll) return kth(tree[root].l,y);
if (y>tree[root].ll && y<=tree[root].ll+tree[root].val) return tree[root].key;
if (y>tree[root].ll+tree[root].val) return kth(tree[root].r,y-tree[root].ll-tree[root].val);
}
int pred(int &root,int y){
if (!root) return -oo;
if (y<=tree[root].key) return pred(tree[root].l,y);
if (y>tree[root].key) return max(tree[root].key,pred(tree[root].r,y));
}
int succ(int &root,int y){
if (!root) return oo;
if (y>=tree[root].key) return succ(tree[root].r,y);
if (y<tree[root].key) return min(tree[root].key,succ(tree[root].l,y));
}
int main(){
srand(0);
scanf("%d",&m);
for (int i=1;i<=m;++i){
int x,y;
scanf("%d%d",&x,&y);
switch (x){
case 1:insert(root,y);break;
case 2:del(root,y);break;
case 3:printf("%d\n",rank(root,y));break;
case 4:printf("%d\n",kth(root,y));break;
case 5:printf("%d\n",pred(root,y));break;
case 6:printf("%d\n",succ(root,y));break;
}
}
return 0;
}
By Charlie Pan
Mar 6,2014