新姿势 树剖求LCA

倍增是求LCA用的最多的算法板子,但是一直不会手拍,但是最近发现了一个新姿势,就是树剖求LCA,发现新大陆

树剖代码:

void Dfs1(int u,int f){
    fa[u]=f;
    siz[u]=1;
    dep[u]=dep[f]+1;
    for(int i=head[u]; i!=-1; i=nex[i]){
        int v=to[i];
        if(v==f) continue;
        Dfs1(v,u);
        siz[u]+=siz[v];
        if(siz[v]>siz[son[u]]){
            son[u]=v;
        }
    }
}
void Dfs2(int u, int tp){
    tip[u]=tot++;
    top[u]=tp;
    if(son[u]) Dfs2(son[u],tp);
    for(int i=head[u]; i!=-1; i=nex[i]){
        int v=to[i];
        if(son[u]==v||v==fa[u]) continue;
        Dfs2(v,v);
    }
}

 

那么怎么用树剖求LCA呢?

这个时候就要祭出区间操作的代码了

void get_sum(int u,int v,int n){
    int ans=0;
    while(top[u]!=top[v]){
        if(dep[top[v]]<dep[top[u]]) swap(u,v);
        ans+=query_sum(1,tip[top[v]],tip[v],1,n);
        v=fa[top[v]];
    }
    if(de[u]<de[v]) swap(u,v);
    ans+=query_sum(1,tip[v],tip[u],1,n);
    printf("%d\n",ans);
}

这段代码什么意思呢,很明显,树剖后映射到线段树后区间求和嘛,通过这个代码可以知道,区间求和是每次在u v中找一条top深度大重链经行的计算,然后更新u,这样反复知道top相同。。。发现什么了没有,top相同,说明一定在同一条重链上说明一定在同一条链上,那么,深度小的就是LCA了

代码:

int LCA(int u,int v){
    int ans=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]<dep[top[v]]) swap(u,v);
        u=fa[top[u]];
    }
    if(dep[u]>dep[v]) swap(u,v);
    return u;
}

 

转载于:https://www.cnblogs.com/max88888888/p/7258787.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值