倍增法求解LCA

倍增法求解LCA

不限于二叉树

pow(2,k-1)+pow(2,k-1)=pow(2,k)

倍增法的关键数组f[a][i]表示节点a的第2i个祖先,f[a][0]就是a的父亲

先DFS一遍,预处理f数组,再求解lca

求解lca的函数是先让更深的点上跳到另一点的深度,再让两者一起往上跳,直到两者lca的儿子,最后直接返回其中一点的父亲即可

代码示例

//链式前向星存图
#define N 100005
struct Edge{
    int next,to;
}e[2*N];
int cnt;
int head[N];
int f[N][21],depth[N];

void Add_edge(int from,int to){
    e[++cnt].to=to;
    e[cnt].next=head[from];
    head[from]=cnt;
}

void dfs(int u,int father){
    f[u][0]=father;
    depth[u]=depth[father]+1;
    for(int i=1;depth[u]>=(1<<i);i++){
        f[u][i]=f[f[u][i-1]][i-1];
    }
    for(int i=head[u];i;i=e[i].next){
        int v=e[i].to;
        if(v==father) continue;
        dfs(v,u);
    }
}
int lca(int x,int y){
    if(depth[x]<depth[y]) swap(x,y);//让x深度更深
    //用位掩码的方法把x抬到和y同深
    int diff=depth[x]-depth[y];
    for(int i=0;i<=20;i++){
        if(diff&(1<<i)) x=f[x][i];
    }
    if(x==y) return x;
    for(int i=20;i>=0;i--){
        if(f[x][i]!=f[y][i]){
            x=f[x][i];
            y=f[y][i];
        }
    }
    return f[x][0];
}
posted @ 2026-03-02 01:01  江蝶  阅读(2)  评论(0)    收藏  举报