P3379 模板最近公共祖先(LCA)(欧拉序+rmq)
Posted kafuuchino
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3379 模板最近公共祖先(LCA)(欧拉序+rmq)相关的知识,希望对你有一定的参考价值。
用欧拉序$+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 ",ask(read(),read())); return 0; }
以上是关于P3379 模板最近公共祖先(LCA)(欧拉序+rmq)的主要内容,如果未能解决你的问题,请参考以下文章