zoukankan      html  css  js  c++  java
  • 替罪羊树模板(题目:普通平衡树)

    我要喷写这题题解的人,害得我调错了 $n$ 多个小时!!

      1 #include<bits/stdc++.h>
      2 #define lc tr[o].l
      3 #define rc tr[o].r
      4 #define N 100001
      5 #define inf 2147483647
      6 const double alpha=0.7;
      7 using namespace std;
      8 inline int read(){
      9     int x=0; bool f=1; char c=getchar();
     10     while(!isdigit(c)){if(c=='-') f=0; c=getchar();}
     11     while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0'; c=getchar();}
     12     if(!f) return 0-x;
     13     return x;
     14 }
     15 int n,root,op,x,cnt;
     16 int v[N];
     17 int bad,fa;
     18 bool exist,son;
     19 namespace ForceTree{
     20     struct node{
     21         int l,r,val,siz,cnt;
     22         bool deleted;
     23     }tr[N<<2];
     24     vector<int>v;
     25     inline bool isbad(int o){
     26         //cout<<tr[lc].cnt<<' '<<tr[rc].cnt<<' '<<alpha*tr[o].cnt+5<<' '<<(tr[lc].cnt>alpha*tr[o].cnt+5)<<' '<<(tr[rc].cnt>alpha*tr[o].cnt+5)<<'
    ';
     27         return tr[lc].cnt>alpha*tr[o].cnt+5 || tr[rc].cnt>alpha*tr[o].cnt+5;
     28     }
     29     inline void pushup(int o){
     30         tr[o].siz = (!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf)+tr[lc].siz+tr[rc].siz;
     31         tr[o].cnt = 1+tr[lc].cnt+tr[rc].cnt;
     32     }
     33     void dfs(int o){
     34         if(lc) dfs(lc);
     35         if(!tr[o].deleted) v.push_back(o);
     36         if(rc) dfs(rc);
     37     }
     38     void build(int &o,int l,int r){
     39         if(l>=r){o=0; return;} //o=0,注意!不然某个叶子结点的儿子可能没刷掉! 
     40         int mid=(l+r)>>1;
     41         o=v[mid];
     42         //printf("build:%d %d %d %d
    ",o,tr[o].val,l,r);
     43         build(lc,l,mid), build(rc,mid+1,r);
     44         pushup(o);
     45     }
     46     void rebuild(int &o){
     47         //printf("rebuild
    ");
     48         v.clear();
     49         dfs(o);
     50         build(o,0,v.size());
     51     }
     52     void insert(int &o,int x){
     53         if(!o){
     54             o=++cnt;
     55             lc=rc=0;
     56             tr[o].deleted=0;
     57             if(x==-inf || x==inf) tr[o].siz=0;
     58             else tr[o].siz=1;
     59             tr[o].cnt=1;
     60             tr[o].val=x;
     61             return;
     62         }
     63         else{
     64             if(x!=-inf && x!=inf) ++tr[o].siz;
     65             ++tr[o].cnt;
     66             if(x<tr[o].val){
     67                 insert(lc,x);
     68                 if(bad==lc) fa=o, son=0; //bad点的父亲到后面要更新儿子 
     69             }
     70             else{
     71                 insert(rc,x);
     72                 if(bad==rc) fa=o, son=1;
     73             }
     74             if(isbad(o)) bad=o; //优化? 
     75         }
     76     }
     77     int rank(int o,int x){
     78         int ans=1;
     79         while(o){
     80             //printf("%d %d %d
    ",tr[o].val,tr[o].siz,tr[lc].siz);
     81             if(x<=tr[o].val){
     82                 if(x==tr[o].val) exist=1;
     83                 o=lc;
     84             }
     85             else{
     86                 //printf("%d %d
    ",tr[lc].siz,(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted));
     87                 ans+=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted);
     88                 o=rc;
     89             }
     90         }
     91         return ans;
     92     }
     93     int kth(int o,int x){
     94         //printf("rank:%d
    ",x);
     95         if(x<=0) return -inf;
     96         while(o){
     97             //printf("%d %d
    ",tr[o].val,tr[lc].siz);
     98             if(!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf && tr[lc].siz+1==x) return tr[o].val;
     99             if(x<=tr[lc].siz) o=lc;
    100             else{
    101                 x-=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted);
    102                 o=rc;
    103             }
    104         }
    105         return inf;
    106     }
    107     void erase(int o,int rk){
    108         if(!exist) return;
    109         while(o){
    110             if(!tr[o].deleted && tr[o].val!=inf && tr[o].val!=-inf && tr[lc].siz+1==rk){
    111                 //printf("erase:%d %d
    ",tr[o].val,x);
    112                 if(tr[o].val==x) tr[o].deleted=1, --tr[o].siz;
    113                 return;
    114             }
    115             --tr[o].siz;
    116             if(rk<=tr[lc].siz) o=lc;
    117             else{
    118                 rk-=tr[lc].siz+(tr[o].val!=-inf && tr[o].val!=inf && !tr[o].deleted);
    119                 o=rc;
    120             }
    121         }
    122     }
    123 };
    124 using namespace ForceTree;
    125 int main(){
    126     //freopen("rand.in","r",stdin);
    127     //freopen("count.out","w",stdout);
    128     n=read();
    129     insert(root,-2147483647), insert(root,2147483647);
    130     while(n--){
    131         op=read(),x=read();
    132         if(op==1){
    133             bad=-1;
    134             insert(root,x);
    135             if(bad!=-1){
    136                 //printf("bad:%d %d %d %d
    ",root,fa,bad,tr[bad].val);
    137                 if(bad==root) rebuild(bad), root=bad; //注意!! 
    138                 else{
    139                     rebuild(bad);
    140                     if(!son) tr[fa].l=bad;
    141                     else tr[fa].r=bad;
    142                 }
    143             }
    144         }
    145         if(op==2){
    146             exist=0;
    147             erase(root,rank(root,x));
    148         }
    149         if(op==3) printf("%d
    ",rank(root,x));
    150         if(op==4) printf("%d
    ",kth(root,x));
    151         if(op==5) printf("%d
    ",kth(root,rank(root,x)-1));
    152         if(op==6) printf("%d
    ",kth(root,rank(root,x+1)));
    153     }
    154     return 0;
    155 }
    156 /*
    157 3
    158 1 87
    159 1 68
    160 3 50
    161 
    162 45
    163 1 914241
    164 1 639471
    165 5 917713
    166 6 912745
    167 1 234811
    168 1 297728
    169 3 297728
    170 1 6927
    171 5 645391
    172 1 664569
    173 2 914241
    174 1 134689
    175 1 868271
    176 1 842266
    177 5 850426
    178 1 286545
    179 4 1
    180 1 333833
    181 1 274177
    182 1 568845
    183 1 157569
    184 4 13
    185 1 732493
    186 4 7
    187 4 9
    188 5 646117
    189 1 136381
    190 1 473089
    191 1 419305
    192 1 639776
    193 3 473089
    194 4 7
    195 6 234571
    196 1 37685
    197 1 321207
    198 1 496713
    199 1 531105
    200 2 234811
    201 2 157569
    202 1 326601
    203 1 317437
    204 1 791873
    205 1 931097
    206 1 224521
    207 3 317437
    208 
    209 50
    210 1 1
    211 1 2
    212 1 3
    213 1 4
    214 1 5
    215 1 6
    216 1 7
    217 1 8
    218 1 9
    219 1 10
    220 1 11
    221 1 12
    222 1 13
    223 1 14
    224 1 15
    225 1 16
    226 1 17
    227 1 18
    228 1 19
    229 1 20
    230 1 21
    231 1 22
    232 1 23
    233 1 24
    234 
    235 5
    236 1 1
    237 1 5
    238 2 5
    239 3 4
    240 */
    View Code
  • 相关阅读:
    前端之JQuery:JQuery文档操作
    前端之JQuery:JQuery属性操作
    前端之JQuery:JQuery基本语法
    前端之JavaScript:JS之DOM对象三
    前端之JavaScript:JS之DOM对象二
    初始django
    mysql 索引
    多表查询
    单表查询
    外键的三种形式
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/9856246.html
Copyright © 2011-2022 走看看