ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

全局平衡二叉树

2019-04-28 11:55:25  阅读:428  来源: 互联网

标签:重链 int tot si 二叉树 平衡 now 全局


全局平衡二叉树

考虑重链剖分的时候,我们实际上是对每条重链的这个局部开一个数据结构维护,而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\n",las=max(mx[root].a,mx[root].c));
    }
    return 0;
}

标签:重链,int,tot,si,二叉树,平衡,now,全局
来源: https://www.cnblogs.com/butterflydew/p/10783032.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有