• 【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 }
  • 相关阅读:
    windows下虚拟环境安装方法
    用python 将 pymysql操作封装成类
    通过python的logging模块输出日志文件
    详细User-Agent大全
    多个结果显示成一个group_concat函数
    pytest 失败用例重试
    Python selenium 三种等待方式详解
    自定义列标题 case when
    查询结果多个合并一个GROUP_CONCAT(EmployeeName)
    win7_32虚拟机网络设置
  • 原文地址:https://www.cnblogs.com/skylynf/p/7140472.html
Copyright © 2020-2023  润新知