Problem Link
\(dis(u,v)\) 表示 \(u\) 到 \(v\) 在原来那棵树上的距离,可以用倍增lca \(O(\log n)\) 求
从 \(a\) 走到 \(b\)
不走新边,那么距离 \(len_1=dis(a,b)\)
因为树上的边可以随便走,所以只要 \(len_1\) 与 \(k\) 同奇偶并且 \(len_1 \le k\) 那么就可以输出 \(\texttt{YES}\) 了
否则,就强制走新边
有两种情况,一种是从 \(a\) 走到 \(x\) ,再过新边走到 \(y\) ,再从 \(y\) 走到 \(b\)
\(len_2=dis(a,x)+1+dis(y,b)\)
一种是从 \(a\) 走到 \(y\) ,再过新边走到 \(x\) ,再从 \(x\) 走到 \(b\)
\(len_3=dis(a,y)+1+dis(x,b)\)
对于 \(len_2\) 和 \(len_3\) ,跟上面 \(len_1\) 一样判断就行了
时间复杂度 \(O(q\log n)\)
// This code wrote by chtholly_micromaker(MicroMaker)
#include
#define reg register
#define int long long
using namespace std;
const int MaxN=300050;
struct Edge
{
int nxt,to;
}E[MaxN<<2];
template inline void read(t &s)
{
s=0;
reg int f=1;
reg char c=getchar();
while(!isdigit(c))
{
if(c=='-')
f=-1;
c=getchar();
}
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
s*=f;
return;
}
int hd[MaxN],en,n;
int up[MaxN][21],dep[MaxN];
inline void adde(int u,int v)
{
++en;
E[en]=(Edge){hd[u],v};
hd[u]=en;
return;
}
inline void dfs(int u,int fa)
{
up[u][0]=fa;
for(int i=hd[u];~i;i=E[i].nxt)
{
reg int v=E[i].to;
if(v==fa)
continue;
dep[v]=dep[u]+1;
dfs(v,u);
}
return;
}
inline void Init_lca()
{
for(int k=1;k<21;++k)
for(int i=1;i<=n;++i)
up[i][k]=up[up[i][k-1]][k-1];
return;
}
inline int lca(int u,int v)
{
if(dep[u]=0;--k)
if(dep[up[u][k]]>=dep[v])
u=up[u][k];
if(u==v)
return u;
for(int k=20;k>=0;--k)
if(up[u][k]!=up[v][k])
u=up[u][k],v=up[v][k];
return up[u][0];
}
inline int getdis(int u,int v)
{
return dep[u]+dep[v]-2*dep[lca(u,v)];
}
signed main(void)
{
memset(hd,-1,sizeof hd);
reg int u,v;
cin>>n;
for(int i=1;i>q;
reg int a,b,k;
for(int i=1;i<=q;++i)
{
read(u);read(v);read(a);read(b);read(k);
reg int len=getdis(a,b);
if((len%2==k%2)&&len<=k)
{
puts("YES");
continue;
}
reg int len1=getdis(a,u)+getdis(b,v)+1;
if(len1==k)
{
puts("YES");
continue;
}
reg int len2=getdis(a,v)+getdis(b,u)+1;
if(len2==k)
{
puts("YES");
continue;
}
if((len1%2==k%2)&&len1<=k)
{
puts("YES");
continue;
}
if((len2%2==k%2)&&len2<=k)
{
puts("YES");
continue;
}
// printf(" %d %d %d\n",len,len1,len2);
puts("NO");
}
return 0;
}