LCA模板

倍增
#include<bits/stdc++.h>
using namespace std;
//#define int long long
struct Tree {
	int nxt,to;
} edge[500005*4];
int cnt,head[500005*4];
int n,m,s,fa[500005][25],dep[500005],lg[500005];
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int read() {
	int x=0,f=1;
	char ch=nc();
	while(ch<48||ch>57) {
		if(ch=='-')
			f=-1;
		ch=nc();
	}
	while(ch>=48&&ch<=57)
		x=x*10+ch-48,ch=nc();
	return x*f;
}
void write(int x) {
	if(x<0)
		putchar('-'),x=-x;
	if(x>9)
		write(x/10);
	putchar(x%10+'0');
	return;
}
void add(int u,int v) {
	cnt++;
	edge[cnt].nxt=head[u];
	edge[cnt].to=v;
	head[u]=cnt;
}
void dfs(int u,int fat) { //fa[i][j]:节点i的2^j级祖先
	fa[u][0]=fat,dep[u]=dep[fat]+1;
	for(int i=1; i<=lg[dep[u]]; i++)
		fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int i=head[u]; i; i=edge[i].nxt) {
		int v=edge[i].to;
		if(v==fat)continue;
		dfs(v,u);
	}
}
int LCA(int x,int y) {
	if(dep[x]<dep[y])swap(x,y);
	while(dep[x]>dep[y])
		x=fa[x][lg[dep[x]-dep[y]]-1];
	if(x==y)return x;
	for(int k=lg[dep[x]]-1; k>=0; k--)
		if(fa[x][k]!=fa[y][k])
			x=fa[x][k],y=fa[y][k];
	return fa[x][0];
}
signed main() {
	n=read(),m=read(),s=read();
	for(int i=1; i<n; i++) {
		int x,y;
		x=read(),y=read();
		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);
	for(int i=1; i<=m; i++) {
		int x=read(),y=read();
		write(LCA(x,y));
		putchar('\n');
	}
	return 0;
}
注意 lg[i]:log2(i)+1
一定要用scanf 或者快读 用ios::sync_with_stdio(false)会被卡T
posted @ 2023-01-24 10:15  PKU_IMCOMING  阅读(14)  评论(0)    收藏  举报