RT,方法是找lca再用dfs序分别判断两个lca是否出现在另外一条路径上
代码:
#include<bits/stdc++.h>
#define N 100005
using namespace std;
inline int read()
{
int x=0; char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x;
}
int n;
int fa[N][22],dep[N],lg[N],size[N],dfn[N],tim;
vector<int>e[N];
inline void dfs(int x,int f)
{
dfn[x]=++tim;
fa[x][0]=f,dep[x]=dep[f]+1,size[x]=1;
for(int i=1;i<lg[dep[x]];++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=0;i<e[x].size();++i){
int t=e[x][i];
if(t==f) continue;
dfs(t,x);
size[x]+=size[t];
}
}
inline 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 i=lg[dep[x]]-1;i>=0;--i)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
inline bool solve(int x1,int y1,int x2,int y2)
{
int l1=lca(x1,y1),l2=lca(x2,y2);
if(dep[x1]>=dep[l2]&&dfn[x1]<=dfn[l2]+size[l2]-1&&dep[l2]>=dep[l1]&&dfn[l2]<=dfn[l1]+size[l1]-1) return 1;
if(dep[y1]>=dep[l2]&&dfn[y1]<=dfn[l2]+size[l2]-1&&dep[l2]>=dep[l1]&&dfn[l2]<=dfn[l1]+size[l1]-1) return 1;
if(dep[x2]>=dep[l1]&&dfn[x2]<=dfn[l1]+size[l1]-1&&dep[l1]>=dep[l2]&&dfn[l1]<=dfn[l2]+size[l2]-1) return 1;
if(dep[y2]>=dep[l1]&&dfn[y2]<=dfn[l1]+size[l1]-1&&dep[l1]>=dep[l2]&&dfn[l1]<=dfn[l2]+size[l2]-1) return 1;
return 0;
}
int main()
{
n=read(); int q=read();
for(int i=1;i<n;++i){
int x=read(),y=read();
e[x].push_back(y),e[y].push_back(x);
}
for(int i=1;i<=n;++i) lg[i]=lg[i-1]+((1<<lg[i-1])==i);
dfs(1,1);
for(int i=1;i<=q;++i){
int x1=read(),y1=read(),x2=read(),y2=read();
if(solve(x1,y1,x2,y2)) putchar('Y'),putchar('\n');
else putchar('N'),putchar('\n');
}
return 0;
}