1 #include<cstdio> 2 #include<cstring> 3 #include<ctime> 4 #include<cmath> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<set> 11 #include<map> 12 #define rep(i,l,r) for(int i=(l);i<=(r);i++) 13 #define clr(a,x) memset(a,x,sizeof(a)) 14 using namespace std; 15 typedef long long ll; 16 typedef pair<int,int> pii; 17 #define mkp(a,b) make_pair(a,b) 18 int read(){ 19 int ans=0,f=1; 20 char c=getchar(); 21 while(!isdigit(c)){ 22 if(c=='-') f=-1; 23 c=getchar(); 24 } 25 while(isdigit(c)){ 26 ans=ans*10+c-'0'; 27 c=getchar(); 28 } 29 return ans*f; 30 } 31 const int maxn=500009,inf=0x3fffffff; 32 struct node{ 33 int s,v,r; 34 node*ch[2]; 35 inline void maintain(){ 36 s=ch[0]->s+ch[1]->s+1; 37 } 38 }pool[maxn<<2],*root,*pt=pool,*null; 39 int n; 40 node*newnode(int x){ 41 pt->s=1;pt->ch[0]=pt->ch[1]=null; 42 pt->r=rand()*rand(); 43 pt->v=x; 44 return pt++; 45 } 46 void rot(node*&o,int d){ 47 node*t=o->ch[d^1]; 48 o->ch[d^1]=t->ch[d];t->ch[d]=o; 49 o->maintain();t->maintain(); 50 o=t; 51 } 52 void insert(node*&o,int x){ 53 if(o==null) o=newnode(x); 54 else{ 55 if(x<o->v){ 56 insert(o->ch[0],x); 57 if(o->ch[0]->r>o->r) rot(o,1); 58 }else{ 59 insert(o->ch[1],x); 60 if(o->ch[1]->r>o->r) rot(o,0); 61 } 62 } 63 o->maintain(); 64 } 65 void del(node*&o,int x){ 66 if(o->v==x){ 67 if(o->ch[0]!=null&&o->ch[1]!=null){ 68 if(o->ch[0]->r>o->ch[1]->r){ 69 rot(o,1);del(o->ch[1],x); 70 }else{ 71 rot(o,0);del(o->ch[0],x); 72 } 73 }else if(o->ch[0]!=null) o=o->ch[0]; 74 else o=o->ch[1]; 75 }else{ 76 if(x<o->v) del(o->ch[0],x); 77 else del(o->ch[1],x); 78 } 79 if(o!=null) o->maintain(); 80 } 81 int rank(node*o,int x){ 82 if(o==null) return inf; 83 if(x==o->v) return min(rank(o->ch[0],x),o->ch[0]->s+1); 84 if(x<o->v) return rank(o->ch[0],x); 85 return rank(o->ch[1],x)+o->ch[0]->s+1; 86 } 87 int num(node*o,int x){ 88 if(x==o->ch[0]->s+1) return o->v; 89 if(x<=o->ch[0]->s) return num(o->ch[0],x); 90 return num(o->ch[1],x-o->ch[0]->s-1); 91 } 92 int pre(node*o,int x){ 93 if(o==null) return -1; 94 return x<=o->v?pre(o->ch[0],x):max(o->v,pre(o->ch[1],x)); 95 } 96 int suc(node*o,int x){ 97 if(o==null) return inf; 98 return x>=o->v?suc(o->ch[1],x):min(o->v,suc(o->ch[0],x)); 99 } 100 void init(){ 101 null=newnode(0); 102 null->s=null->r=0; 103 root=null; 104 } 105 int main(){ 106 init(); 107 n=read(); 108 rep(i,1,n){ 109 int opt=read(),x=read(); 110 if(opt==1) insert(root,x); 111 else if(opt==2) del(root,x); 112 else if(opt==3) printf("%d ",rank(root,x)); 113 else if(opt==4) printf("%d ",num(root,x)); 114 else if(opt==5) printf("%d ",pre(root,x)); 115 else printf("%d ",suc(root,x)); 116 } 117 return 0; 118 }
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3847 Solved: 1575
[Submit][Status][Discuss]
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
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
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]