普通平衡树

不知道花了多少个日日夜夜,所以我觉得自己是个傻逼,以为一定写对的前驱和后驱却是卡了我不知道多久的原因,知道我确信其他操作百分之百没有问题时才来看我这个傻逼的迭代前驱写法,换成递归就过了。自己真是傻逼啊。不过这也算是我用指针写对的第一个平衡树吧。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。呵呵呵呵呵呵呵呵呵呵呵呵呵呵红红火火恍恍惚惚。

我想我的弱,和傻逼已经无可奉告发可说了。

posted @ 2017-04-03 17:58  rsqppp  阅读(146)  评论(0)    收藏  举报