倍增做法#4 TLE了求条(玄关)
查看原帖
倍增做法#4 TLE了求条(玄关)
879242
SJZ08楼主2025/1/20 21:07

代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e6+5,M=2e6+5;
int h[N],e[M],ne[M],idx;
int fa[N][30],depth[N];
void add(int x,int y) {
	e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}
void dfs(int u,int f) {
	fa[u][0]=f;
	depth[u]=depth[f]+1;
	for (int i=1;i<=20;i++) {
		fa[u][i]=fa[fa[u][i-1]][i-1];
	}
	for (int i=h[u];~i;i=ne[i]) {
		int x=e[i];
		if (x==f) continue;
		dfs(x,u);
	}
}
int lca(int x,int y) {
	if (depth[x]<depth[y]) swap(x,y);
	for (int i=20;i>=0;i--) {
		if (depth[fa[x][i]]>=depth[y]) {
			x=fa[x][i];
		}
	}
	if (x==y) return x;
	for (int i=20;i>=0;i--) {
		if (fa[x][i]!=fa[y][i]) {
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	return fa[x][0];
}
int main() {
	memset(h,-1,sizeof h);
	int n,u,m;
	scanf("%d %d %d",&n,&u,&m);
	for (int i=1;i<n;i++) {
		int x,y;
		scanf("%d %d",&x,&y);
		add(x,y);
		add(y,x);
	}
	dfs(1,0);
	while (m--) {
		int v,time;
		scanf("%d %d",&v,&time);
		int l=lca(u,v);
		if (depth[u]+depth[v]-2*depth[l]<=time) {
			u=v;
			printf("%d ",u);
			continue;
		}
		if (depth[u]-depth[l]>=time) {
			for (int i=0;i<=20;i++) {
				if ((time&(1<<i))==(1<<i)) {
					u=fa[u][i];
				}
			}
			printf("%d ",u);
		}else {
			time-=(depth[u]-depth[l]);
			time=depth[v]-depth[l]-time;
			for (int i=0;i<=20;i++) {
				if ((time&(1<<i))==(1<<i)) {
					v=fa[v][i];
				}
			}
			u=v;
			printf("%d ",v);
		}
	}
	return 0;
}
2025/1/20 21:07
加载中...