哇比赛的时候查不出来wtcl。。
还有,我不相信是 E 题
题意 Description
给定一个 \(n\) 个点的树,相邻点的距离为 \(1\) 。
\(q\) 个询问,每个询问包含5个整数: \(x,y,a,b,k\)。
含义是:在原树上新连上一条边 \((x,y)\) ,要求判断一下从 \(a\) 点是否有距离为 \(k\) 的到 \(b\) 的路径。
注意:
每个询问是独立的,即上次询问加上的边,不能为这一次的询问所用。
这一条路径也许会重复经过某一条边或某一点。
题解 Solution
涉及树上距离,考虑 LCA 。
对于每个询问,我们先判断一下 \(a,b\) 间有没有长度为 \(k\) 的路径,再判断一下经过边 \(x,y\) 的路径有没有长度为 \(k\) 的即可。
对于第一个:
下面的 \(\operatorname{dist}(u,v)\) 表示 \(u,v\) 的最短距离。
快速求得 \(\operatorname{dist}(u,v)\) 可以通过 LCA 来求,公式: \(\operatorname{dist}(u,v)=depth_u+depth_v-2\times depth_{\operatorname{LCA}(u,v)}\) 。其中 \(\operatorname{LCA}(u,v)\) 表示结点 \(u,v\) 的 最近公共祖先。
先求出 \(a,b\) 的最短距离 \(D = \operatorname{dist}(a,b)\)。假如说 \(D\) 与 \(k\) 的奇偶性一致且 \(k\ge D\) 的话,那么就是
YES
。为什么是奇偶性?因为如果把这条最短的路径“折一下”(1->2->3->4
折成1->2->3->2->3->4
),总长度会加二,奇偶性不变。倘若 \(k\ge D\) ,那么这样一直折下去,路径长度一定可以到达 \(k\) 。对于新加入的边,我们计算出 \(D'=\min (\operatorname{dist}(a,x)+\operatorname{dist}(b,y)+1,\operatorname{dist}(a,y)+\operatorname{dist}(b,x)+1)\),即 \(a\) 到 \(b\) 经过边 \((x,y)\) 的最短路径的长度。如果 \(D'\) 与 \(k\) 的奇偶性一致且 \(k \ge D'\) 的话就是可行的。
注意, \(D\) 或 \(D'\) 必须 \(\le k\) 否则是不成立的。因为“折”是不可以“折”负数次的。
代码 Source Code
#include
#include
#include
#include
using namespace std;
int get_int()
{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
x=x*10+c-'0',c=getchar();
return f*x;
}
const int N=1e5+5;
vector G[N];
int depth[N],father[N];
int maxson[N],size[N],top[N]/*link tops*/;
int n,s,m;
void DFS1(const int &now,const int &from)
{
father[now]=from,depth[now]=depth[from]+1,size[now]=1;
for(register int i=0;i1)DFS2(maxson[now],lktp);
for(register int i=0;i=depth[top[v]])?u=father[top[u]]:v=father[top[v]];
return depth[u]
- P.S. LCA部分是用树链剖分写的,倍增或 RMQ 也可以。
算法复杂度 \(\Theta (n+q\log n)\)