普通平衡树
不知道花了多少个日日夜夜,所以我觉得自己是个傻逼,以为一定写对的前驱和后驱却是卡了我不知道多久的原因,知道我确信其他操作百分之百没有问题时才来看我这个傻逼的迭代前驱写法,换成递归就过了。自己真是傻逼啊。不过这也算是我用指针写对的第一个平衡树吧。sign~~AC的时候彻底怀疑了我的智商。我真是个傻逼!!!!!!!
妈的一定要记下这让我痛苦的代码。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 #include<cstdlib> 5 #include<cstring> 6 using namespace std; 7 struct Node{ 8 int v,r,s,w; 9 Node* ch[2]; 10 int cmp(int x){ 11 if(v == x) return -1; 12 else return x < v?0:1; 13 } 14 void maintain(){ 15 s = w; 16 if(ch[0] != NULL) s+= ch[0]->s; 17 if(ch[1] != NULL) s+= ch[1]->s; 18 } 19 Node(){ 20 v = s = w = 0; 21 } 22 }; 23 Node* root; 24 int ans; 25 Node* newnode() 26 { 27 Node* k = new Node(); 28 k->r = rand(); 29 k->ch[0] = k->ch[1] = NULL; 30 return k; 31 } 32 33 void roteta(Node* &o,int d) 34 { 35 Node* k = o->ch[d^1];o->ch[d^1] = k->ch[d];k->ch[d] = o; 36 o->maintain();k->maintain();o = k; 37 } 38 void insert(Node* &o,int x) 39 { 40 if(o == NULL){ 41 o = newnode(); 42 o->v = x; 43 o->w ++; 44 }else{ 45 int d = o->cmp(x); 46 if(d == -1) o->w ++; 47 else{ 48 insert(o->ch[d],x); 49 if(o->ch[d]->r > o->r ){ 50 roteta(o,d^1); 51 } 52 } 53 } 54 if(o != NULL) o->maintain(); 55 } 56 57 void remove(Node* &o,int x) 58 { 59 if(o == NULL) return; 60 int d = o->cmp(x); 61 if(d == -1){ 62 if(o->w > 1) o->w --; 63 else{ 64 if(o->ch[0] == NULL) o = o->ch[1]; 65 else if(o->ch[1] == NULL) o = o->ch[0]; 66 else{ 67 int d2 = o->ch[0]->r > o->ch[1]->r ?0:1; 68 roteta(o,d2^1);remove(o,x); 69 } 70 } 71 }else remove(o->ch[d],x); 72 if(o != NULL) o->maintain(); 73 } 74 75 int rank(Node* o,int x) 76 { 77 if(o == NULL) return 0; 78 int d = o->cmp(x); 79 int s = (o->ch[0]==NULL?0:o->ch[0]->s); 80 if(d == -1) return s +1; 81 else if(d == 0) return rank(o->ch[0],x); 82 else return rank(o->ch[1],x)+o->w+s; 83 } 84 85 int kth(Node* o,int x) 86 { 87 if(o == NULL||x<0 ||o->s < x) return 0; 88 int s = o->ch[0] == NULL?0:o->ch[0]->s; 89 if(x <= s) return kth(o->ch[0],x); 90 else if(x > s + o->w) 91 return kth(o->ch[1],x - o->w -s); 92 else return o->v; 93 } 94 void prelink(Node* o,int x) 95 { 96 if(o == NULL) return ; 97 if(o->v < x){ 98 ans = o->v; 99 prelink(o->ch[1],x); 100 }else{ 101 prelink(o->ch[0],x); 102 } 103 } 104 void lastlink(Node* o,int x) 105 { 106 if(o == NULL) return; 107 if(o->v > x){ 108 ans = o->v; 109 lastlink(o->ch[0],x); 110 }else{ 111 lastlink(o->ch[1],x); 112 } 113 } 114 int main() 115 { 116 int n;scanf("%d",&n); 117 int flag ,x; 118 for(int i = 0;i < n;i++) 119 { 120 scanf("%d%d",&flag,&x); 121 if (flag == 1) insert(root,x); 122 else if(flag == 2) remove(root,x); 123 else if(flag == 3) printf("%d\n",rank(root,x)); 124 else if(flag == 4) printf("%d\n",kth(root,x)); 125 else if(flag == 5) prelink(root,x),printf("%d\n",ans); 126 else if(flag == 6) lastlink(root,x),printf("%d\n",ans); 127 } 128 return 0; 129 }
草草草,以后誰说迭代求前驱好我跟他急。
然后这个傻逼东西BZOJ跑了480ms,排名1059。呵呵呵呵呵呵呵呵呵呵呵呵呵呵红红火火恍恍惚惚。
我想我的弱,和傻逼已经无可奉告发可说了。

浙公网安备 33010602011771号