lca

potential-star發表於2024-04-20

倍增求lca

struct edge{
    int v,w;
};
//思考:要想知道一個數有幾個二級制位,直接n=__lg(x)
//我們可以知道<n最近的2的次冪,9最大的是8,8雖然是2的3次方,但要遍歷它的每一位
//需要3到0開始,也就是考慮到0的影響,我們可以正好滿足偏移。
//2的3次方有四位,也就是__lg(x)就是我們需要的最高位,從它開始往低遍歷
vector<edge>e[N];
int dep[N];
int d[N];
const int len=__lg(N);
int f[N][len+2];
int cnt[N];
int ans=0;
void dfs(int u,int fa){
    dep[u]=dep[fa]+1;
    f[u][0]=fa;
    for(int i=1;i<=len;i++)f[u][i]=f[f[u][i-1]][i-1];
    //預處理倍增陣列

    for(auto [v,w]:e[u]){
        if(v==fa)continue;
        d[v]=d[u]+w;
        dfs(v,u);
    }
}

int lca(int x,int y){
    if(dep[x]<dep[y])swap(x,y);
    for(int i=len;i>=0;i--){
        if(dep[f[x][i]]>=dep[y])x=f[x][i];
    }
    //跳到相同深度

    if(x==y)return y;
    //提提前判本身就是祖先關係


    for(int i=len;i>=0;i--){
        if(f[x][i]!=f[y][i]){
            x=f[x][i];y=f[y][i];
        }
    }
    //倍增一起向上跳,直到父親就是答案
    return f[x][0];
}


相關文章