就是比二叉查找树多了几个点
1.左旋右旋的时候记得更新子树节点个数,外面如果不旋转要直接++cnt
2.之前遇到相等的值向右插的方法能够保证查找“值为x”的最小节点下标时,搜到的第一个点下标最小。然而,在←→旋之后这一性质可能被破坏(比如{data=3,r=1},{data=1,r=4},{data=1,r=3}
1 #include<stdio.h> 2 #include<cstdlib> 3 #include<ctime> 4 #define lch ch[0] 5 #define rch ch[1] 6 using namespace std; 7 const int maxN = 600002; 8 int n; 9 int brand() 10 { 11 int a = rand(), b = rand(); 12 return ((a&0x7FFF) << 15) | (b&0x7FFF); 13 } 14 struct node 15 { 16 int data, cnt, r; 17 node* ch[2]; 18 node() 19 {data = 0; cnt = 1; r = brand(); ch[0] = ch[1] = 0;} 20 }; 21 typedef node* pnode; 22 pnode root = 0; 23 int num(pnode t) 24 {return t ? t->cnt : 0;} 25 void maintain(pnode &t, int d) 26 { 27 pnode p = t->ch[d]; 28 t->ch[d] = p->ch[d^1]; 29 p->ch[d^1] = t; 30 t->cnt = num(t->lch) + num(t->rch) + 1; 31 p->cnt = num(p->lch) + num(p->rch) + 1; 32 t = p; 33 } 34 void addn(pnode &t, int x) 35 { 36 if(!t) 37 { 38 t = new node; 39 t->data = x; 40 return; 41 } 42 if(t->data > x) 43 { 44 addn(t->lch,x); 45 if(t->r > t->lch->r) 46 maintain(t,0); 47 else 48 ++t->cnt; 49 } 50 else 51 { 52 addn(t->rch,x); 53 if(t->r > t->rch->r) 54 maintain(t,1); 55 else 56 ++t->cnt; 57 } 58 } 59 int require(pnode t, int x) 60 { 61 if(!t) 62 return -2; 63 if(t->data > x) 64 return require(t->lch,x); 65 if(t->data == x) 66 { 67 int tmp = require(t->lch,x); 68 return tmp == -2 ? num(t->lch) : tmp; 69 } 70 int tmp = require(t->rch,x); 71 return tmp == -2 ? -2 : (tmp + num(t->lch) + 1); 72 } 73 int ask(pnode t, int x) 74 { 75 if(!t || x < 1 || x > num(t)) 76 return -1; 77 if(x < num(t->lch) + 1) 78 return ask(t->lch,x); 79 if(x > num(t->lch) + 1) 80 return ask(t->rch,x-num(t->lch)-1); 81 return t->data; 82 } 83 int main() 84 { 85 srand(time(0)); 86 //freopen("ipt.txt","r",stdin); 87 //freopen("opt2.txt","w",stdout); 88 char opt; int inp; 89 scanf("%d",&n); 90 getchar(); 91 while(n--) 92 { 93 scanf("%c",&opt); getchar(); scanf("%d",&inp); getchar(); 94 //printf("opt=%c inp=%d\n",opt,inp); 95 if(opt == 'I') 96 addn(root,inp); 97 else if(opt == 'R') 98 printf("%d\n",require(root,inp)+1); 99 else 100 printf("%d\n",ask(root,inp)); 101 } 102 return 0; 103 }
(显然未完待续。。。)