零分倍增求调
查看原帖
零分倍增求调
649114
50lty12楼主2023/5/24 13:46
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,st,m,a,b,k,x,y,nw,p,dt,c,c2;
int head[N],dep[N],f[N][22];
struct AB{
	int a,b,n;
}d[N*2];
void cun(int a,int b){
	d[++k].a=a,d[k].b=b;
	d[k].n=head[a],head[a]=k;
}
void dfs1(int now,int la){
	for(int i=head[now]; i; i=d[i].n){
		int nxt=d[i].b;
		if(nxt==la) continue;
		f[nxt][0]=now;
		dep[nxt]=dep[now]+1;
		dfs1(nxt,now);
	}
}
int lca(int x,int y){
	if(dep[x]<dep[y]) swap(x,y);
	dt=dep[x]-dep[y];
	for(int i=21; i>=0; i--){
		if(dt>=(1<<i)){
			dt-=(1<<i);
			x=f[x][i];
		}
	}
	if(x==y) return x;
	for(int i=21; i>=0; i--){
		if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
	}
	return f[x][0];
}
int dist(int x,int y){
	return dep[x]+dep[y]-2*dep[lca(x,y)];
}
int main(){
	scanf("%d%d%d",&n,&st,&m);
	for(int i=1; i<n; i++){
		scanf("%d%d",&a,&b);
		cun(a,b);
		cun(b,a);
	}
	dfs1(1,0);
	for(int j=1; j<22; j++){
		for(int i=1; i<=n; i++){
			f[i][j]=f[f[i][j-1]][j-1];
		}
	}
	nw=st;
	while(m--){
		scanf("%d%d",&x,&y);
		p=lca(nw,x);
		if(dist(nw,x)<=y) nw=x;
		else{
			c=dep[nw]-dep[p];
			if(c>=y){
				c-=y;
				for(int i=21; i>=0; i--){
					if(c>=(1<<i)){
						c-=(1<<i);
						nw=f[nw][i];
					}
				}
			}
			else{
				c2=dist(nw,x)-c;
				nw=y;
				for(int i=21; i>=0; i--){
					if(c2>=(1<<i)){
						c2-=(1<<i);
						nw=f[nw][i];
					}
				}
			}
		}
		printf("%d ",nw);
	}
	return 0;
}
2023/5/24 13:46
加载中...