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;
}
快得多
posted @ 2023-01-26 14:58  PKU_IMCOMING  阅读(14)  评论(0)    收藏  举报