zoukankan      html  css  js  c++  java
  • 新姿势 树剖求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
    ",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;
    }
  • 相关阅读:
    vim 的列操作
    关于 matplotlib
    freemarker的常用内建函数
    三次握手与四次挥手
    layui动态表格生成
    layui 解决浏览器自动填充form表单账号和密码输入框的问题
    手机验证 和身份证验证
    把动态查询出来的集合数据,横向展示在页面
    eclipse安装freemarker插件
    目录文件树jQuery Ztree基本用法
  • 原文地址:https://www.cnblogs.com/max88888888/p/7258787.html
Copyright © 2011-2022 走看看