Luogu P3398 仓鼠找sugar

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

inline void swap(int &a,int &b){a=a^b;b=a^b;a=a^b;}

inline int abs(int x){return x>0?x:-x;}

int n,q,a,b,c,d,head[100005],dep[100005],fa[100005][25],cnt;

//fa开小了QwQ调了一个小时(YP:把我命调没了) 

struct edge{
	int v,next;
}e[500005];

inline void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].next=head[u];
	head[u]=cnt;
}

inline void dfs(int u,int fau){
	dep[u]=dep[fau]+1;
	fa[u][0]=fau;
	for(int i=1;(1<<i)<=dep[u];i++)fa[u][i]=fa[fa[u][i-1]][i-1];
	for(int i=head[u];i!=-1;i=e[i].next){
		if(e[i].v!=fau)dfs(e[i].v,u);
	}
}

inline int lca(int x,int y){
	if(dep[x]<dep[y])swap(x,y);
	for(int i=20;i>=0;i--)
		if(dep[x]-dep[y]>=(1<<i))x=fa[x][i];
	if(x==y)return y;
	for(int i=20;i>=0;i--){
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];y=fa[y][i];
		}
	}
	return fa[y][0];
}

inline int dis(int x,int y){//这个思路很重要 
	int u=lca(x,y);
	return abs(dep[x]-dep[u])+abs(dep[y]-dep[u]);
}

inline bool on(int a,int x,int y){//这个思路很重要 
	if(dis(x,a)+dis(a,y)==dis(x,y))return 1;
	return 0;
}

int main(){
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n-1;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		add(u,v);
		add(v,u);
	}
	dfs(1,0);//这一行没写调了半小时
	while(q--){
		scanf("%d%d%d%d",&a,&b,&c,&d);
		int u1=lca(a,b),u2=lca(c,d);
		if(on(u1,c,d)||on(u2,a,b))printf("Y\n");
		else printf("N\n");
	}
}
posted @ 2019-08-08 21:38  Y15BeTa  阅读(104)  评论(0编辑  收藏  举报