树链剖分总结 hdu 3966 Aragorn's Story 洛谷 3384 洛谷 2146 软件包管理器 poj 2763 Housewife Wind fzu 2082 过路费 poj 3237 Tree hdu 4718 The LCIS on the Tree hdu 5052 Yaoge’s maximum profit hdu 5029 Relief grain

所谓树链剖分就是把树上的路径转化为连续的区间从而用各种数据结构解决树上的问题。

而转化为区间则是利用其重链的性质把一条树上的路径变成很多连续的重链从而加速找两点的lca。

并在节点向上跳的过程中对区间用数据结构做更新操作,或是将连续的重链保存做离线操作。

常见的树链剖分有更新链或子树的权值并求其权值。权值也可以换成任何可以在连续区间用数据结构解决的其他询问。

一、

首先需要对树进行预处理,通过一次dfs找出每个节点的父亲节点、重儿子节点、以及节点下子树的大小、节点深度。

dep[M]:深度

f[M]:父亲

son[M]:重儿子

sz[M]:子树大小

void dfs(int u,int fa,int d){
    sz[u]=1,dep[u]=d,f[u]=fa,son[u]=-1;
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==fa) continue;
        dfs(v,u,d+1);
        sz[u]+=sz[v];//update size
        if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;//子树大小最大的儿子是重儿子
    }
    return ;
}
dfs(1,-1,1)进入
View Code

二、

由上一步预处理出的信息进而得到每条重链的起始节点为之后的剖分加速。以及处理树的dfs序把所有的子树和重链变为连续的区间。

top[M]:每条重链的起始节点,将重儿子连接起来的链称为重链。

rnk[M]:连续区间中的下标在树中的编号。

id[M]:树中节点在连续区间里的编号。

void dfs1(int u,int t){
    id[u]=++tot;//dfs序
    rnk[tot]=u;
    top[u]=t;//重链上的top都为链的起始节点
    if(son[u]==-1) return ;
    dfs1(son[u],t);//先更新重儿子使得重链是连续的区间
    for(int i=head[u];~i;i=e[i].next){
        int v=e[i].v;
        if(v==f[u]||v==son[u]) continue;
        dfs1(v,v);//轻儿子是其重链的起始节点
    }
    return ;
}

dfs1(1,1)进入
View Code

三、

将询问的的路径剖分为不同的重链即连续的区间。在连续的区间中可以用各种数据结构搞事情。

void update1(int x,int y,int v){
    int fx=top[x],fy=top[y];//把节点指向其重链的起始节点
    while(fx!=fy){//如果这两个点不在一条重链上则一直向上跳
        if(dep[fx]>dep[fy]){//fx节点深度更深
            update(id[fx],id[x],1,n,1,v);
            x=f[fx],fx=top[x];//从这条重链爬到父节点的重链上去
        }
        else{//同理
            update(id[fy],id[y],1,n,1,v);
            y=f[fy],fy=top[y];
        }
    }
    if(dep[x]<dep[y])//在一条重链中时深度可能不相等
        update(id[x],id[y],1,n,1,v);
    else
        update(id[y],id[x],1,n,1,v);
}

//路径的查询操作与更新操作基本一致。
View Code

四、

写好数据结构。

例题:

hdu 3966 Aragorn's Story    区间更新路径权值,单点查询权值。

洛谷 3384    区间更新+区间查询。

洛谷 2146 软件包管理器    支持链与子树的更新与查询

poj 2763 Housewife Wind&&fzu 2082 过路费    处理边权而非点权,边权可以映射到点权里去。

poj 3237 Tree    单点更新,区间取反,区间查询。

hdu 4718 The LCIS on the Tree    树链剖分+求区间LCIS

hdu 5052 Yaoge’s maximum profit     树链剖分+线段树合并

hdu 5029 Relief grain     树链剖分+权值线段树

猜你喜欢

转载自www.cnblogs.com/LMissher/p/9568463.html
今日推荐