• bzoj3224: Tyvj 1728 普通平衡树


    就是写替罪羊模版的。

    有一件非常恐怖的事情,就是我在ins的时候判是否重建,第7个点就会跑13秒

    然后删了就A了!!A了???

    upd:我尝试把平衡因子改成0.5也能过,从0.5开始往上加复杂度就逐渐增加。

    upd2:发现是递归版本的ins从下往上修改,所以从上往下修改问题就不大了。

    upd3:发现现在还是从下往上修改,但是只改一次。有点玄学。

    upd:感觉这个东西很不可用啊。。。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const double alpha=0.75;
    
    struct node
    {
        int c,son[2],tot,siz,alive;//tot表示管理节点总数(纯属用来判重建)siz表示除去被删除的节点的总数,alive表示该点是否被删 
    }tr[210000];int root;
    int top,sta[210000];//用于回收空间
    
    int Llen,L[110000];//得出暴力重建的子树的中序遍历 
    void gotravel(int x)
    {
        if(x==0)return ;
        gotravel(tr[x].son[0]);
        
        if(tr[x].alive==1)L[++Llen]=x;
        else sta[++top]=x;
        
        gotravel(tr[x].son[1]);
    }
    int build(int l,int r)//重建与值无关,只是改变树的形态 
    {
        if(l>r)return 0;
        if(l==r)
        {
            int x=L[l];
            tr[x].son[0]=tr[x].son[1]=0;
            tr[x].tot=tr[x].siz=1;
            return x;
        }
        int mid=(l+r)/2;
        int x=L[mid];
        tr[x].son[0]=build(l,mid-1);
        tr[x].son[1]=build(mid+1,r);
        
        int lc=tr[x].son[0],rc=tr[x].son[1];
        tr[x].tot=tr[lc].tot+tr[rc].tot+1;
        tr[x].siz=tr[lc].siz+tr[rc].siz+1;
        
        return x;
    }
    void rebuild(int f,int x,int w)
    {
        Llen=0;gotravel(x);
        int tt=build(1,Llen);
        if(f!=0)tr[f].son[w]=tt;
        else root=tt;
    }//------------rebuild------------------
    
    void add(int f,int d,int w)
    {
        int x=sta[top];top--;
        tr[x].c=d;
        tr[x].son[0]=tr[x].son[1]=0;
        tr[x].tot=tr[x].siz=1;
        tr[x].alive=1;
        
        if(f!=0)tr[f].son[w]=x;
        else root=x;
    }
    int tlen,tmp[110000];
    void ins(int d) 
    {
        if(root==0)
        {
            add(0,d,0);
            return ;
        }
        
        int x=root;
        tlen=0;tmp[0]=0;tmp[++tlen]=x;
        while(x!=0)
        {
            tr[x].tot++;tr[x].siz++;
            int lc=tr[x].son[0],rc=tr[x].son[1];
            if(d<=tr[x].c)
            {
                if(lc==0){add(x,d,0);break;}
                else x=lc, tmp[++tlen]=x;
            }
            else
            {
                if(rc==0){add(x,d,1);break;}
                else x=rc, tmp[++tlen]=x;
            }
        }
        
        for(int i=tlen;i>=1;i--)
        {
            int x=tmp[i];
            int lc=tr[x].son[0],rc=tr[x].son[1];
            if( (double(tr[x].siz))*alpha > (double(max(tr[lc].siz,tr[rc].siz))) )
            {
                int gf=tmp[i-1],goat=x,w;
                if(tr[gf].son[0]==goat)w=0;
                else w=1;
                rebuild(gf,goat,w);
                break;
            }
        }
    }//--------------------ins-------------------
    
    int findrank(int d)
    {
        int x=root,ret=1;
        while(x!=0)
        {
            if(d<=tr[x].c)x=tr[x].son[0];
            else ret+=tr[tr[x].son[0]].siz+tr[x].alive, x=tr[x].son[1];
        }
        return ret;
    }
    void del(int d)
    {
        int x=root,k=findrank(d);
        while(x!=0)
        {
            tr[x].siz--;
            int lc=tr[x].son[0],rc=tr[x].son[1];
            if(tr[lc].siz+1==k&&tr[x].alive==1){tr[x].alive=0;break;}
            else if(k<=tr[lc].siz)x=lc;
            else k-=tr[lc].siz+tr[x].alive, x=rc;
        }
        if( (double(tr[root].tot))*alpha > (double(tr[root].siz)) )rebuild(0,root,0);
    }//--------------------del--------------------
    
    //------------------simple---------------
    
    int findmath(int k)
    {
        int x=root;
        while(x!=0)
        {
            int lc=tr[x].son[0],rc=tr[x].son[1];
            if(tr[lc].siz+1==k&&tr[x].alive==1)return tr[x].c;
            else if(k<=tr[lc].siz)x=lc;
            else k-=tr[lc].siz+tr[x].alive, x=rc;
        }
    }
    
    //----------for the problem------------
    
    int main()
    {
        freopen("ptszs.in","r",stdin);
        freopen("ptszs.out","w",stdout);
        int n,op,x;
        scanf("%d",&n);
        root=0;
        for(int i=205000;i>=1;i--)sta[++top]=i;
        for(int i=1;i<=n;i++)
        {
            scanf("%d%d",&op,&x);
                 if(op==1)ins(x);
            else if(op==2)del(x);
            else if(op==3)printf("%d
    ",findrank(x));
            else if(op==4)printf("%d
    ",findmath(x));
            else if(op==5)printf("%d
    ",findmath(findrank(x)-1));
            else if(op==6)printf("%d
    ",findmath(findrank(x+1)));
        }
        return 0;
    }
  • 相关阅读:
    刷题-力扣-112. 路径总和
    刷题-力扣-1137. 第 N 个泰波那契数
    刷题-力扣-101. 对称二叉树
    刷题-力扣-99. 恢复二叉搜索树
    刷题-力扣-109. 有序链表转换二叉搜索树
    刷题-力扣-108. 将有序数组转换为二叉搜索树
    刷题-力扣-111. 二叉树的最小深度
    刷题-力扣-110. 平衡二叉树
    2019春Python程序设计练习6(0423--0429)
    2019春Python程序设计练习5(0416--0422)
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8601446.html
Copyright © 2020-2023  润新知