zoukankan      html  css  js  c++  java
  • 倍增算法

    树上倍增

    倍增算法就是通过倍增快速查找的算法。它在树的问题上比树链剖分处理得要快而且简单。

    它的核心公式就是fa[x][j]=fa[fa[x][j-1]][j-1] / fa[x][j+1]=fa[fa[x][j]][j].为了更好地理解这个公式,我打了以下表格:

      0 1 2 3
    1 0 0 0 0
    2 1(1+2^0) 0 0 0
    3 2 1(1+2^1) 0 0
    4 3 2 0 0
    5 4 3 1(1+2^2) 0
    6 5 4 2 0
    7 6 5 3 0
    8 7 6 4 0
    9 8 7 5 1(1+2^3)

    看得出来,横行表示的是2的幂数,也就是fa[x][j]中的j。

    将j和x颠倒似乎能优化。

    那么每次dfs一个点的时候,我们先记录fa[x][0]为该点的直接父亲,然后将它初始化:

    for (register int i=0;fa[x][i];++i) fa[x][i+1]=fa[fa[x][i]][i];

    若要求两点的LCA,首先要记录它们的深度,然后倍增:

    inline int LCA(int u,int v)
    {
        if(dep[u]<dep[v])swap(u,v);
        for(R int i=0;i<=16;i++)
            if((dep[u]-dep[v])&(1<<i))u=fa[u][i];
        if(u==v)return u;
        for(R int i=16;i>=0;i--)
            if(fa[u][i]!=fa[v][i])u=fa[u][i],v=fa[v][i];
        return fa[u][0];
     } 

    毕竟,指数爆炸可是很快的。这是一个清清楚楚的logn的复杂度。

  • 相关阅读:
    SharedPreferences
    短信发送器的实现
    第四周总结
    本周开发工作时间及内容
    自我总结
    随笔
    结对编程
    目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
    八皇后
    数制转换
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13200154.html
Copyright © 2011-2022 走看看