LCA 树链剖分版
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2*1e6+10;
inline char nc() {
static char buf[MAXN],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;
}
inline int read() {
char c=nc();
int x=0,f=1;
while(c<'0'||c>'9') {
if(c=='-')f=-1;
c=nc();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0',c=nc();
}
return x*f;
}
struct Tree {
int u,to,nxt;
} edge[MAXN];
int head[MAXN];
int num=1;
struct SegTree {
int l,r,w,add;
} tr[MAXN];
int N,M,root,MOD,cnt=0,a[MAXN],b[MAXN];
inline void AddEdge(int u,int v) {
num++;
edge[num].to=v;
edge[num].nxt=head[u];
head[u]=num;
}
int dep[MAXN],fa[MAXN],son[MAXN],siz[MAXN],top[MAXN],idx[MAXN];
void dfs1(int u,int fat,int depth) {
dep[u]=depth;
fa[u]=fat;
siz[u]=1;
int maxson=-1;
for(int i=head[u]; i; i=edge[i].nxt) {
int v=edge[i].to;
if(v==fat) continue;
dfs1(v,u,depth+1);
siz[u]+=siz[v];
if(siz[v]>maxson)maxson=siz[v],son[u]=v;
}
}
void dfs2(int u,int topf) {
idx[u]=++cnt;
a[cnt]=b[u];
top[u]=topf;
if(!son[u]) return ;
dfs2(son[u],topf);
for(int i=head[u]; i; i=edge[i].nxt)
if(!idx[edge[i].to])
dfs2(edge[i].to,edge[i].to);
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
int main() {
N=read();
M=read();
root=read();
for(int i=1; i<=N-1; i++) {
int x=read(),y=read();
AddEdge(x,y);
AddEdge(y,x);
}
dfs1(root,0,1);
dfs2(root,root);
while(M--) {
int x=read(),y=read();
printf("%d\n",LCA(x,y));
}
return 0;
}
快得多
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号