CF1304E 1-Trees and Queries
Posted chinesepikaync
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1304E 1-Trees and Queries相关的知识,希望对你有一定的参考价值。
(dis(u,v)) 表示 (u) 到 (v) 在原来那棵树上的距离,可以用倍增lca (O(log n)) 求
从 (a) 走到 (b)
不走新边,那么距离 (len_1=dis(a,b))
因为树上的边可以随便走,所以只要 (len_1) 与 (k) 同奇偶并且 (len_1 le k) 那么就可以输出 ( exttt{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(qlog n))
// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
#define int long long
using namespace std;
const int MaxN=300050;
struct Edge
{
int nxt,to;
}E[MaxN<<2];
template <class t> 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]<dep[v])
swap(u,v);
if(u!=v)
for(int k=20;k>=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<n;++i)
{
read(u);read(v);
adde(u,v);
adde(v,u);
}
dep[1]=1;dfs(1,0);
Init_lca();
int q;cin>>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("<test> %d %d %d
",len,len1,len2);
puts("NO");
}
return 0;
}
以上是关于CF1304E 1-Trees and Queries的主要内容,如果未能解决你的问题,请参考以下文章
[CF1304E] 1-Trees and Queries - LCA
CF-div2-620-E. 1-Trees and Queries LCA 树上点距离