倍增的思是二进制,二进制需要进行位运算
        首先开一个n×logn的数组,比如fa[n][logn],其中fa[i][j]表示i节点的第2^j个父亲是谁。

然后,我们会发现有这么一个性质:   fa[i][j]=fa [fa[i][j-1]] [j-1]

用文字叙述为:i的第2^j个父亲 是 i的第2^(j-1)个父亲的第2^(j-1)个父亲。

个人理解这个性质 认为 : 2^j = 2^(j-1) + 2^(j-1)   

求 i 的第K个父亲  需要将K拆分分成多个满足 2^n 的数相加

int father(int i,int k)
{
    for(int x=0;x<=int(log2(k));x++)
        if((1<<x)&k)    //(1<<x)&k可以判断k的二进制表示中,第x位上是否为1  ,1左移x位与K的x位 进行与(&)计算。
i=fa[i][x]; //把i往上 加一个k满足的2^n, 当循环结束,所有的2^n都加上,即找到了第K个父亲。 return i; }

用树上倍增的时候,用dfs预处理出 每一个数的所有的父节点,即fa[n][logn] 数组,便于后面查询父节点。

如果待处理的树有n个节点,那么最多有一个节点会有2^(logn)个父亲,所以我们的fa数组第二维开logn就够了。

(depth[i]表示i的深度,这个可以一起处理出来,以后要用)

//nowp=nowposition  fa=father 
void dfs(int nowp,int fa){
    depth[nowp] =depth[fa]+1;
    father[nowp][0]=fa;
    for(int j=1;j <=lg[depth[nowp]]+1;++j)
        father[nowp][j]=father [father[nowp][j-1]][j-1];
    for(int i=0;i<G[nowp].size();++i){
        if(G[nowp][i]!=fa)
            dfs(G[nowp][i],nowp);
    }
}

这样,我们在nlogn的时间内可以通过一遍dfs处理出这棵树的相关信息。 倍增的应用中,最基础的应该就是求LCA(最近公共祖先),时间复杂度是logn。

对于求u、v的LCA,我们可以先把u、v用倍增法把深度大的提到和另一个深度相同。如果此时u、v已经相等了,表示原来u、v就在一条树链上,直接返回此时的结果。

        如果此时u、v深度相同但不等,则证明他们的lca在更“浅”的地方,此时需要把u、v一起用倍增法上提到他们的父亲相等。为啥是提到父亲相等呢?因为倍增法是一次上提很多,所以有可能提“过”了,如果是判断他们本身作为循环终止条件,就无法判断是否提得过多了,所以要判断他们父亲是否相等。

int LCA(int u,int v){
    if(depth[u]<depth [v]) swap(u,v);
//int dc = depth[u]-depth[v];
//    for(int j=0;j<maxbit;++j)
//    {
//        if((dc>>j)&1) u=father[u][j];
//    }
    while(depth[u]!=depth[v]){
        u=father[u][lg[depth[u]-depth[v]]];
    }
    if(u ==v) return u;
    for(int j= lg[depth[u]];j>=0;--j){
        if(father[u][j]!=father[v][j]){
            u=father[u][j];
            v=father[v][j];
        }

    }
    return father[u][0];
} 

树上倍增的真正意义

例题: 给你一棵树和两个点x和y,求这两点间路径的路径最大/小的点权/边权

我们可以设dis[i][j] 表示i到他的第2^j 个祖先的路径最大值,就可以边求LCA 边顺便求出两点距离

还有求两点的路径上路径权值和呢?

设sum[i][j] 表示i到他的第2^j个祖先的路径权值和,同时也可边求LCA边求和,

因为 sum[i][j]=sum[i][j−1]+sum[anc[i][j−1]][j−1]) 

像RMQ求LCA ,是无法解决这类问题的

参考链接:

https://blog.csdn.net/saramanda/article/details/54963914

https://blog.csdn.net/enjoy_pascal/article/details/78277008

12-24 17:04