zoukankan      html  css  js  c++  java
  • 替罪羊树

    优雅即是暴力!

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

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

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

      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 }
  • 相关阅读:
    原码、反码、补码详解
    进制转换
    目录
    Window【目录】
    排序算法——冒泡排序
    算法的时间复杂度与空间复杂度
    排序算法
    递归—八皇后问题
    递归—迷宫问题
    递归
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11512927.html
Copyright © 2011-2022 走看看