• LCA倍增


    #include <iostream>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    
    using namespace std;
    
    const int maxn=5e5+10;
    
    int depth[maxn],fa[maxn][22],lg[maxn];
    int tot;
    int head[maxn<<1],e[maxn<<1],nex[maxn<<1];
    void add(int x,int y)
    {
        e[++tot]=y;
        nex[tot]=head[x];
        head[x]=tot;
    }
    
    void dfs(int cur,int fath)
    {
        depth[cur]=depth[fath]+1;
        fa[cur][0]=fath;
        for(int i=1; (1<<i)<=depth[cur]; i++)
        {
            fa[cur][i]=fa[fa[cur][i-1]][i-1];
        }
        for(int i=head[cur]; i!=-1; i=nex[i])
        {
            if(e[i]==fath)
                continue;
            dfs(e[i],cur);
        }
    }
    
    int lca(int x,int y)
    {
        if(depth[x]<depth[y])
            swap(x,y);
        while(depth[x]>depth[y])
            x=fa[x][lg[depth[x]-depth[y]]-1];
        if(x==y)
            return x;
        for(int i=lg[depth[x]]-1;i>=0;i--)
        {
            if(fa[x][i]!=fa[y][i])
                x=fa[x][i],y=fa[y][i];
        }
        return fa[x][0];
    }
    
    int main()
    {
        memset(head,-1,sizeof(head));
        int n,m,s,x,y;
        scanf("%d %d %d",&n,&m,&s);
        for(int i=1;i<n;i++)
        {
            scanf("%d %d",&x,&y);
            add(x,y);add(y,x);
        }
        for(int i=1;i<=n;i++)
        {
            lg[i]=lg[i-1]+(1<<lg[i-1]==i);
        }
        dfs(s,0);
        while(m--)
        {
            scanf("%d %d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    

      

  • 相关阅读:
    fwt
    fft,ntt
    loj6077
    高维前缀和
    hihocoder 1496 寻找最大值
    HDU 5977 Garden of Eden
    扩展crt
    有标号的DAG计数I~IV
    BZOJ 3160 万径人踪灭
    Codeforces Round #524 (Div. 2) F
  • 原文地址:https://www.cnblogs.com/wyhbadly/p/11536594.html
Copyright © 2020-2023  润新知