【题意】
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]
【代码】
#include<stdio.h> #include<stdlib.h> #include<time.h> #define INF 20000000 struct Node { Node* ch[2]; int v,s,r; int cmp_v(int x) const { if(x==v) return -1; if(x<v) return 0; if(x>v) return 1; } int cmp_s(int x) const { if(x==ch[0]->s+1) return -1; if(x<=ch[0]->s) return 0; if(x>ch[0]->s+1) return 1; } }; Node *root,*null,*t; int min(int a,int b) { if(a<b) return a; return b; } int max(int a,int b) { if(a>b) return a; return b; } void init() { null=new Node(); null->ch[0]=null->ch[1]=NULL; null->v=null->s=null->r=0; root=null; } void gets(Node* o) { o->s = o->ch[0]->s + o->ch[1]->s + 1; } void xz(Node* &o,int d) { Node* k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; gets(o); gets(k); o=k; } void tj(Node* &o,int x) { int d=o->cmp_v(x); if(o==null) { o=new Node(); o->ch[0]=o->ch[1]=null; o->v=x; o->s=1; o->r=rand(); return; } o->s++; if(d!=1) d=0; tj(o->ch[d],x); if( o->ch[d]->r > o->r ) xz(o,d^1); } void sc(Node* &o,int x) { int d=o->cmp_v(x); if(d!=-1) { o->s--; sc(o->ch[d],x); return; } if(o->ch[0]==null) o=o->ch[1]; else { if(o->ch[1]==null) o=o->ch[0]; else { if( o->ch[0]->r > o->ch[1]->r) d=0; else d=1; xz(o,d^1); o->s--; sc(o->ch[d^1],x); } } } int getrank(Node* &o,int x) { int d=o->cmp_v(x); if(o==null) return 1; if(d==1) return o->ch[0]->s+1+getrank(o->ch[1],x); return getrank(o->ch[0],x); } int getnum(Node* &o,int x) { int d=o->cmp_s(x); if(d==-1) return o->v; if(d==1) x = x - o->ch[0]->s - 1; return getnum(o->ch[d],x); } int last(Node* &o,int x) { int d=o->cmp_v(x); if(o==null) return -INF; if(d!=1) return last(o->ch[0],x); return max(o->v,last(o->ch[1],x)); } int next(Node* &o,int x) { int d=o->cmp_v(x); if(o==null) return INF; if(d!=0) return next(o->ch[1],x); return min(o->v,next(o->ch[0],x)); } int main() { int n,i,opt,x; scanf("%d",&n); init(); for(i=1;i<=n;i++) { scanf("%d%d",&opt,&x); if(opt==1) tj(root,x); if(opt==2) sc(root,x); if(opt==3) printf("%d\n",getrank(root,x)); if(opt==4) printf("%d\n",getnum(root,x)); if(opt==5) printf("%d\n",last(root,x)); if(opt==6) printf("%d\n",next(root,x)); } return 0; }