P3379 【模板】最近公共祖先(LCA)(欧拉序+rmq)

P3379 【模板】最近公共祖先(LCA)

用欧拉序$+rmq$维护的$lca$可以做到$O(nlogn)$预处理,$O(1)$查询

这里剻个图

 

 

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int read(){
    char c=getchar(); int x=0;
    while(c<'0'||c>'9') c=getchar();
    while('0'<=c&&c<='9') x=x*10+c-48,c=getchar();
    return x;
}
#define N 500005
int n,m,s,u,v,f[20][N<<1],dfn[N],cc,Log[N<<1];
vector <int> g[N];
void dfs(int x,int fa){
    f[0][dfn[x]=++cc]=x;
    for(int i:g[x]) if(i!=fa) dfs(i,x),f[0][++cc]=x;
}
inline int Min(int x,int y){return dfn[x]<dfn[y]?x:y;}
int ask(int x,int y){
    int l=dfn[x],r=dfn[y]; if(l>r)swap(l,r);
    int k=Log[r-l+1];
    return Min(f[k][l],f[k][r-(1<<k)+1]);
}
int main(){
    n=read(); m=read(); s=read(); Log[0]=-1;
    for(int i=1;i<n;++i){
        u=read(); v=read();
        g[u].push_back(v);
        g[v].push_back(u);
    }dfs(s,0);
    for(int i=1;i<=cc;++i) Log[i]=Log[i>>1]+1;
    for(int i=1;i<=Log[cc];++i)
        for(int j=1;j+(1<<i)-1<=cc;++j)
            f[i][j]=Min(f[i-1][j],f[i-1][j+(1<<(i-1))]);
    while(m--) printf("%d\n",ask(read(),read()));
    return 0;
}

 

转载于:https://www.cnblogs.com/kafuuchino/p/11470274.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值