zoukankan      html  css  js  c++  java
  • 【TYVJ1728/BZOJ3224】普通平衡树-替罪羊树

    Problem 普通平衡树

    Solution

    本题是裸的二叉平衡树。有很多种方法可以实现。这里打的是替罪羊树模板。 
    此题极其恶心。 
    前驱后继模块需要利用到rank模块来换一种思路求。 
    很多细节的地方容易炸。我拿数据调了很久才A。 
    (delt()删除模块其实是不需要重建的,不影响时间复杂度) 
    替罪羊树具体详见此篇知乎:替罪羊树

    AC Code

      1 #include "iostream"
      2 #include "cstdio"
      3 #define alpha 0.7
      4 using namespace std;
      5 struct ScapeGoatTree{
      6     int lc,rc,n,w,s,fa;
      7 }a[100010];
      8 struct REbuild{
      9     int n,w;
     10 }d[100010];
     11 void rebuild(int p);
     12 int tot=1,tott=0,top=0,h[100010],n,T,X,root;
     13 int check(int p){
     14     if(a[p].w==0)return 0;
     15     if ((a[a[p].lc].s+a[a[p].lc].w>=double(alpha*(a[p].w+a[p].s)))||
     16         (a[a[p].rc].s+a[a[p].rc].w>=double(alpha*(a[p].w+a[p].s))))return 1;
     17     return 0;
     18 }
     19 int getN(int x){
     20     int now=root;
     21     while(a[now].n!=x&&a[now].s!=0){
     22         if(a[now].n>=x)now=a[now].lc;
     23         else now=a[now].rc;
     24     }
     25     return now;
     26 }
     27 void insr(int x,bool rb){
     28     if(root==0){
     29         root=1;
     30         a[1].n=x;
     31         a[1].w++;
     32         return;
     33     }
     34     int now=root;
     35     while(a[now].s!=0){
     36         if(x==a[now].n){
     37             a[now].w++;
     38             return;
     39         }
     40         if(x>a[now].n&&a[now].rc==0)break;
     41         if(x<a[now].n&&a[now].lc==0)break;
     42         a[now].s++;
     43         if(x>a[now].n)now=a[now].rc;
     44         else if(x<a[now].n)now=a[now].lc;
     45     }
     46 
     47     if(x==a[now].n){
     48         a[now].w++;
     49         return;
     50     }
     51     a[now].s++;
     52     int tmp=now;
     53     if(x>a[now].n)now=a[now].rc=++tot;
     54     else if(x<a[now].n)now=a[now].lc=++tot;
     55     a[now].w++;
     56     a[now].n=x;
     57     if(tmp!=now)a[now].fa=tmp;
     58     int chk=0;
     59     while(now!=root){
     60         now=a[now].fa;
     61         if(check(now))chk=now;
     62     }
     63     if(rb)rebuild(chk);
     64 }
     65 int getnewp(){
     66     if(top>0){
     67         top--;
     68         return h[top+1];
     69     }
     70     else return ++tot;
     71 }
     72 void dfs(int p){
     73     h[++top]=p;
     74     if(a[p].lc!=0)dfs(a[p].lc);
     75     if(a[p].w!=0)d[++tott].n=a[p].n,
     76     d[tott].w=a[p].w;
     77     a[p].s=0;
     78     if(a[p].rc!=0)dfs(a[p].rc);
     79 }
     80 void make(int l,int r,int p,int fa){
     81     int mid=(l+r)/2;
     82     a[p].fa=fa;
     83     a[p].w=d[mid].w;
     84     a[p].n=d[mid].n;
     85     if(mid-1>=l)a[p].lc=getnewp(),make(l,mid-1,a[p].lc,p);else a[p].lc=0;
     86     if(mid+1<=r)a[p].rc=getnewp(),make(mid+1,r,a[p].rc,p);else a[p].rc=0;
     87     a[p].s=a[a[p].lc].w+a[a[p].lc].s+a[a[p].rc].w+a[a[p].rc].s;
     88 }
     89 void rebuild(int p){
     90     if(p==0)return;
     91     tott=0;
     92     dfs(p);
     93     int now=getnewp();
     94     a[now].fa=a[p].fa;
     95     if(p==root)root=now;
     96     int mid=(1+tott)/2;
     97     if(d[mid].n>a[a[p].fa].n)a[a[p].fa].rc=now;
     98     else a[a[p].fa].lc=now;
     99     make(1,tott,now,a[p].fa);
    100 }
    101 void delt(int p,bool rb){
    102     a[p].w--;
    103     int chk=0;
    104     while(p!=root){
    105         p=a[p].fa;
    106         a[p].s--;
    107         if(check(p))chk=p;
    108     }
    109 //  if(rb)rebuild(chk);
    110 }
    111 int XgetRk(int x);
    112 int RkgetX(int x);
    113 int suc(int x){
    114     insr(x+1,0);
    115     int tmp=XgetRk(x+1),nx=getN(x+1);
    116     delt(nx,0);
    117     return RkgetX(tmp);
    118 }
    119 int pre(int x){
    120     insr(x,0);
    121     int tmp=XgetRk(x);
    122     delt(getN(x),0);
    123     return RkgetX(tmp-1);
    124 }
    125 int XgetRk(int x){
    126     int p=getN(x),ans;
    127     ans=a[a[p].lc].s+a[a[p].lc].w;
    128     while(p!=root){
    129         if(a[a[p].fa].rc==p)ans+=a[a[a[p].fa].lc].s+a[a[a[p].fa].lc].w+a[a[p].fa].w;
    130         p=a[p].fa;
    131     }
    132     return ans+1;
    133 }
    134 int RkgetX(int x){
    135     int now=root;
    136     while(true){
    137         int lcS=a[a[now].lc].s+a[a[now].lc].w;
    138         if(x<=lcS)now=a[now].lc;
    139         else if(x>lcS&&x<=a[now].w+lcS)return a[now].n;
    140         else x-=lcS+a[now].w,now=a[now].rc;
    141         if(x==0)return a[now].fa;
    142     }
    143 }
    144 int main(){
    145     scanf("%d",&n);
    146     for(int i=1;i<=n;i++){
    147         if(i%1000==0){
    148             int ttott;
    149             ttott++;
    150         }
    151         scanf("%d%d",&T,&X);                                                        
    152         if(T==1)insr(X,1);  
    153         else if(T==2)delt(getN(X),1);
    154         else if(T==3)printf("%d
    ",XgetRk(X));
    155         else if(T==4)printf("%d
    ",RkgetX(X));
    156         else if(T==5)printf("%d
    ",pre(X));
    157         else if(T==6)printf("%d
    ",suc(X)); 
    158     }   
    159 }
  • 相关阅读:
    函数式宏定义与普通函数
    linux之sort用法
    HDU 4390 Number Sequence 容斥原理
    HDU 4407 Sum 容斥原理
    HDU 4059 The Boss on Mars 容斥原理
    UVA12653 Buses
    UVA 12651 Triangles
    UVA 10892
    HDU 4292 Food
    HDU 4288 Coder
  • 原文地址:https://www.cnblogs.com/skylynf/p/7140472.html
Copyright © 2011-2022 走看看