替罪羊树

优雅即是暴力!

替罪羊树的构建其实就是暴力的构建。

-> 即每次插入的时候我们都判断是否需要重构。

要注意什么什么时候传的是一个引用,什么时候不需要传引用

  1 #include <stdio.h>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <stdbool.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 #include <stack>
  8 #include <map>
  9 #include <vector>
 10 
 11 #define INF 0x3f3f3f3f
 12 using namespace std;
 13 const int maxn = 1e5 + 5;
 14 const double alpha = 0.75;
 15 
 16 
 17 struct Node {
 18     int l,r,val;
 19     int size,fact;
 20     bool exist;
 21 }tzy[maxn];
 22 
 23 int cnt,root;
 24 
 25 void newnode(int &now,int val){
 26     now = ++cnt;
 27     tzy[now].val = val;
 28     tzy[now].size = tzy[now].fact = 1;
 29     tzy[now].exist = true;
 30 }
 31 
 32 
 33 // 判断是否需要重构的条件:
 34 // 当前结点的左子树或右子树的大小大于当前结点的大小  或者  以当前结点为根的子树内被删除结点的个数大于该结点个数的30%
 35 bool imbalence(int now){
 36     if (max(tzy[tzy[now].l].size,tzy[tzy[now].r].size) > tzy[now].size*alpha
 37         ||tzy[now].size-tzy[now].fact>tzy[now].size*0.3){
 38         return true;
 39     }
 40     return false;
 41 }
 42 
 43 vector<int > v;
 44 
 45 void ldr(int now){ // 中序遍历
 46     if (!now)
 47         return ;
 48     ldr(tzy[now].l);
 49     if (tzy[now].exist)
 50         v.push_back(now);
 51     ldr(tzy[now].r);
 52 }
 53 
 54 void lift(int l,int r,int &now){ // now代表当前拎到哪里
 55     if (l == r){
 56         now = v[l];
 57         tzy[now].l = tzy[now].r = 0;
 58         tzy[now].size = tzy[now].fact = 1;
 59         return ;
 60     }
 61     int m = (l + r) >> 1;
 62     while (l < m && tzy[v[m]].val == tzy[v[m-1]].val)
 63         m--;
 64     now = v[m];
 65     if (l < m)
 66         lift(l,m-1,tzy[now].l);
 67     else
 68         tzy[now].l = 0;
 69     lift(m+1,r,tzy[now].r);
 70     tzy[now].size = tzy[tzy[now].l].size + tzy[tzy[now].r].size + 1;
 71     tzy[now].fact = tzy[tzy[now].l].fact + tzy[tzy[now].r].size + 1;
 72 }
 73 
 74 void rebuild(int &now){  // 重构now这个点
 75     v.clear();
 76     ldr(now);
 77     if (v.empty()){
 78         now = 0;
 79         return ;
 80     }
 81     lift(0,v.size()-1,now);
 82 }
 83 
 84 void update(int now,int end){
 85     if (!now){
 86         return;
 87     }
 88     if (tzy[end].val < tzy[now].val){
 89         update(tzy[now].l,end);
 90     }
 91     else
 92         update(tzy[now].r,end);
 93     tzy[now].size = tzy[tzy[now].l].size + tzy[tzy[now].r].size;
 94 }
 95 
 96 void check(int &now,int end){
 97     if (now == end){
 98         return;
 99     }
100     if (imbalence(now)){
101         rebuild(now);
102         update(now,end);
103         return ;
104     }
105     if (tzy[end].val < tzy[now].val){
106         check(tzy[now].l,end);
107     }
108     else
109         check(tzy[now].r,end);
110 }
111 
112 void ins(int &now,int val){
113     if (!now){
114         newnode(now,val);
115         check(root,now);
116         return ;
117     }
118     tzy[now].size++;
119     tzy[now].fact++;
120     if (val < tzy[now].val){
121         ins(tzy[now].l,val);
122     }
123     else
124         ins(tzy[now].r,val);
125 }
126 
127 void del(int now,int val){
128     if (tzy[now].exist && tzy[now].val == val){
129         tzy[now].exist = false;
130         tzy[now].fact--;
131         check(root,now);
132         return ;
133     }
134     tzy[now].fact--;
135     if (val < tzy[now].val)
136         del(tzy[now].l,val);
137     else
138         del(tzy[now].r,val);
139 }
140 
141 int getrank(int val){
142     int now = root,rank = 1;
143     while (now){
144         if (val <= tzy[now].val)
145             now = tzy[now].l;
146         else{
147             rank += tzy[now].exist+tzy[tzy[now].l].fact;
148             now = tzy[now].r;
149         }
150     }
151     return rank;
152 }
153 
154 int getnum(int rank)
155 {
156     int now=root;
157     while(now)
158     {
159         if(tzy[now].exist&&tzy[tzy[now].l].fact+tzy[now].exist==rank)
160             break;
161         else if(tzy[tzy[now].l].fact>=rank)
162             now=tzy[now].l;
163         else
164         {
165             rank-=tzy[tzy[now].l].fact+tzy[now].exist;
166             now=tzy[now].r;
167         }
168     }
169     return tzy[now].val;
170 }
171 
172 int main(){
173     int t;
174     scanf("%d",&t);
175     while(t--)
176     {
177         int opt,x;
178         scanf("%d%d",&opt,&x);
179         switch(opt)
180         {
181             case 1:
182                 ins(root,x);
183                 break;
184             case 2:
185                 del(root,x);
186                 break;
187             case 3:
188                 printf("%d
",getrank(x));
189                 break;
190             case 4:
191                 printf("%d
",getnum(x));
192                 break;
193             case 5:
194                 printf("%d
",getnum(getrank(x)-1));
195                 break;
196             case 6:
197                 printf("%d
",getnum(getrank(x+1)));
198                 break;
199         }
200     }
201     return 0;
202 }
原文地址:https://www.cnblogs.com/-Ackerman/p/11512927.html