倒数第二个点wa,倍增求调
查看原帖
倒数第二个点wa,倍增求调
225287
123321V楼主2024/7/22 17:25

提交记录如下 https://www.luogu.com.cn/record/167816323 不知道为何wa了倒数第二个点

#include <iostream>
#include <cstdio>
using namespace std;

int n,m,s,he[1000005],ne[1000005],tn,t[1000005],d[1000005],f[500005][21],lg[500005];

void qxx(int x,int y){
	tn++;
	t[tn]=y;
	ne[tn]=he[x];
	he[x]=tn;
	return ;
}

void js(int u,int fa){
	d[u]=d[fa]+1;
	f[u][0]=fa;
	for(int i=1;i<=lg[n] && f[u][i-1];i++){
		f[u][i]=f[f[u][i-1]][i-1];
	}
	for(int i=he[u];i;i=ne[i]){
		if(t[i]!=fa) js(t[i],u);
	}
	return ;
}

int lca(int x,int y){
	int l1=x,l2=y;
	if(d[l1]<d[l2]) swap(l1,l2);
	for(int i=lg[n];i>=0 && d[l1]>d[l2];i--){
		if(d[f[l1][i]]>=d[l2]) l1=f[l1][i];
		if(l1==l2) return l1;
	}
	for(int i=lg[n];i>=0;i--){
		if(f[l1][i]!=f[l2][i]){
			l1=f[l1][i];
			l2=f[l2][i];
		}
	}
	return f[l1][0];
}

int main(){
	scanf("%d%d%d",&n,&m,&s);
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		qxx(x,y);
		qxx(y,x);
		if(i>1) lg[i]=lg[i/2]+1;
	}
	lg[n]=lg[n/2]+1;
	js(s,0);
	while(m--){
		int x,y;
		scanf("%d%d",&x,&y);
		printf("%d\n",lca(x,y));
	}
	return 0;
}
2024/7/22 17:25
加载中...