• 全局平衡二叉树


    全局平衡二叉树

    考虑重链剖分的时候,我们实际上是对每条重链的这个局部开一个数据结构维护,而LCT是对整颗树去维护一个大splay,考虑将LCT的思想应用到轻重链剖分中。

    或者

    考虑LCT维护动态dp的时候,每次进行树的形态调整常数是不是过大了,那么考虑运用静态的链剖分,用一个形态不变的平衡树维护整颗树。


    实际上,全局平衡二叉树是一颗二叉树森林,其中的每颗二叉树维护一条重链。但是这个森林里的二叉树又互有联系,其中每个二叉树的根连向这个重链链头的父亲,就像LCT中一样。

    我们的目的是使这个大二叉树森林树高(log)

    于是我们对一条重链构建二叉树的时候,实际上可以理解成每个点点权是带权的,点权为轻子树的点数和+1,然后每次我们取这个链的带权中点作为根,递归处理子树。

    这就是全局平衡二叉树的构造方法。

    在做动态dp修改的时候,如果是二叉树中的父亲是另一条重链中的点,就先把自己的旧贡献去掉,再把新贡献加上,最后updata父亲,否则直接updata父亲就好

    洛谷P4751 【模板】动态 DP(加强版)

    Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    using std::max;
    const int SIZE=(1<<21)+1;
    char ibuf[SIZE],*iS=ibuf,*iT=ibuf;
    #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
    template <class T>
    void read(T &x)
    {
        int f=0;x=0;char c=gc();
        while(!isdigit(c)) f|=c=='-',c=gc();
        while(isdigit(c)) x=x*10+c-'0',c=gc();
        if(f) x=-x;
    }
    const int N=1e6+10;
    int n,m,val[N];
    int head[N],to[N<<1],Next[N<<1],cnt;
    void add(int u,int v)
    {
        to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
    }
    struct Matrix
    {
        int a,b,c,d;
        Matrix(){}
        Matrix(int A,int B,int C,int D){a=A,b=B,c=C,d=D;}
        Matrix friend operator *(Matrix a,Matrix b)
        {
            Matrix ret;
            ret.a=max(a.a+b.a,a.b+b.c);
            ret.b=max(a.a+b.b,a.b+b.d);
            ret.c=max(a.c+b.a,a.d+b.c);
            ret.d=max(a.c+b.b,a.d+b.d);
            return ret;
        }
    }dat[N],mx[N];
    int ch[N][2],par[N],root;
    #define ls ch[now][0]
    #define rs ch[now][1]
    #define fa par[now]
    void updata(int now)
    {
        mx[now]=dat[now];
        if(ls) mx[now]=mx[ls]*mx[now];
        if(rs) mx[now]=mx[now]*mx[rs];
    }
    int siz[N],lsiz[N],dp[N][2],ws[N];
    void dfs(int now,int f)
    {
        siz[now]=lsiz[now]=1;
        dp[now][1]=val[now];
        for(int v,i=head[now];i;i=Next[i])
            if((v=to[i])!=f)
            {
                dfs(v,now);
                siz[now]+=siz[v];
                if(siz[ws[now]]<siz[v]) ws[now]=v;
            }
        for(int v,i=head[now];i;i=Next[i])
            if((v=to[i])!=f&&v!=ws[now])
            {
                lsiz[now]+=siz[v];
                dp[now][1]+=dp[v][0];
                dp[now][0]+=max(dp[v][0],dp[v][1]);
            }
        dat[now]=Matrix(dp[now][0],dp[now][0],dp[now][1],-(1<<30));
        dp[now][1]+=dp[ws[now]][0];
        dp[now][0]+=max(dp[ws[now]][0],dp[ws[now]][1]);
    }
    int s[N],si[N],tot;
    int build(int l,int r)
    {
        if(l>r) return 0;
        int mid=std::lower_bound(si+l,si+r+1,si[r]+si[l-1]>>1)-si,now=s[mid];
        ls=build(l,mid-1);
        rs=build(mid+1,r);
        if(ls) par[ls]=now;
        if(rs) par[rs]=now;
        updata(now);
        return now;
    }
    int dfs1(int now,int f)
    {
        int rt;
        s[++tot]=now;
        si[tot]+=lsiz[now];
        if(ws[now])
        {
            si[tot+1]+=si[tot];
            rt=dfs1(ws[now],now);
        }
        else
        {
            int now=build(1,tot);
            for(int i=1;i<=tot;i++) si[i]=0;
            tot=0;
            return now;
        }
        for(int v,i=head[now];i;i=Next[i])
            if((v=to[i])!=f&&v!=ws[now])
                par[dfs1(v,now)]=now;
        return rt;
    }
    bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
    void upt(int now)
    {
        if(!now) return;
        Matrix las=mx[now];
        updata(now);
        if(fa&&!isroot(now))
        {
            dat[fa].b=(dat[fa].a+=max(mx[now].a,mx[now].c)-max(las.a,las.c));
            dat[fa].c+=mx[now].a-las.a;
        }
        upt(fa);
    }
    int main()
    {
        read(n),read(m);
        for(int i=1;i<=n;i++) read(val[i]);
        for(int u,v,i=1;i<n;i++) read(u),read(v),add(u,v),add(v,u);
        dfs(1,0);
        root=dfs1(1,0);
        for(int las=0,x,y,i=1;i<=m;i++)
        {
            read(x),read(y);
            x^=las;
            dat[x].c+=y-val[x];
            val[x]=y;
            upt(x);
            printf("%d
    ",las=max(mx[root].a,mx[root].c));
        }
        return 0;
    }
    
  • 相关阅读:
    Oracle DUL/AUL/ODU 工具说明
    Mysql 不同版本 说明
    Oracle RAC ASM disk header 备份 恢复 与 重建 示例说明
    Oracle checkpoint 说明
    Oracle RBA(Redo Byte Address) 说明
    Oracle wrap 和 unwrap( 加密与解密) 说明
    Oracle 10.2.0.5.4 Patch Set Update (PSU) – Patch No: p12419392
    Oracle RAC CSS 超时计算 及 参数 misscount, Disktimeout 说明
    Oracle 估算数据库大小的方法
    Oracle 11g 11.2.0.2 Bug 10082277 – Excessive allocation in PCUR or KGLH0 heap of “kkscsAddChildNo”
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10783032.html
Copyright © 2020-2023  润新知