前言

这场比赛,在最后 \(5\) 分钟,我想到了这道题的 \(Idea\),但是,没有打完,比赛就结束了。

正文

题目意思

这道题目的意思就是说,一棵树上每次给 \(x\) 和 \(y\) 节点连 \(1\) 条边,问 \(a\) 到 \(b\) 之间有没有长度为 \(k\) 的边。

分析

一开始,我看到这道题就往基环树这里去想,可实际上,这道题的方法却是和加工零件这道题是有异曲同工之处,作者那道题里面也写了篇题解,不会的同学可以去看一看。

这道题难处理的地方就是加 \(1\) 条边这个地方很难处理,但是我们可以想一想,实际上可能的路径一共就3条

  1. \(a \implies b\) 这是最原始的路径。

  2. \(a \implies x \implies y \implies b\) 这是借助 \(x,y\) 的路径

  3. \(a \implies y \implies x \implies b\) 这是借助 \(y,x\) 的路径。

也就是

bool check(int x,int y){
if(x<=y&&x%2==y%2)return true;
return false;
}
while(T--){
int x,y,a,b,k;
read(x);read(y);read(a);read(b);read(k);
int ab=dist(a,b),ax=dist(a,x),yb=dist(b,y),ay=dist(a,y),bx=dist(b,x);
if(check(ab,k)||check(ax+yb+1,k)||check(ay+bx+1,k))puts("YES");
else puts("NO");
}

处理往回走

可能有读者会问,走到 \(1\) 个点,再走回来,这个怎么办呢?我们发现走到 \(1\) 个点再回来,这样 \(1\) 次路径长度是 \(2\)。所以我们这 \(3\) 条路径当中,只要有 \(1\) 条路径满足一下 \(2\) 个条件,就说明存在这样一条长度为 \(k\) 的路径。

  1. 路径长度 \(\leq k\) 这一个很显然。长度 \(> k\),显然就是不合法的。

  2. 路径长度和 \(k\) 奇偶性相同。这就是基于往回走的做法,奇偶性相同,就代表两个数的差是偶数,所以就是可以组成长度为 \(k\) 路径。

预处理 \(2\) 点之间的距离

我们刚才说了,两个点之间的距离显然是要求出来的,我们需要预处理 \(LCA\),不会的同学可以左转题解区,我用的是最朴素的倍增 \(LCA\)。

void dfs(int x,int f){
dep[x]=dep[f]+1;
fa[x][0]=f;
for(int i=1;(1<<i)<=dep[x];i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=nxt[i])
if(t[i]!=f)dfs(t[i],x);
}
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 k=lg[dep[x]]-1;k>=0;k--)
if(fa[x][k]!=fa[y][k])x=fa[x][k],y=fa[y][k];
return fa[x][0];
}
int dist(int x,int y){//x号节点和y号节点的距离
int z=lca(x,y);
return dep[x]+dep[y]-dep[z]*2;
}

代码

#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &FF){
T RR=1;FF=0;char CH=getchar();
for(;!isdigit(CH);CH=getchar())if(CH=='-')RR=-1;
for(;isdigit(CH);CH=getchar())FF=(FF<<1)+(FF<<3)+(CH^48);
FF*=RR;
}//快读
template<typename T>void write(T x){
if(x<0)putchar('-'),x*=-1;
if(x>9)write(x/10);
putchar(x%10+48);
}//快写
int dep[500010],fa[500010][22],lg[500010],head[500010],nxt[500010],t[500010],tot;
void add(int x,int y){
t[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}//连边
void dfs(int x,int f){
dep[x]=dep[f]+1;
fa[x][0]=f;
for(int i=1;(1<<i)<=dep[x];i++)
fa[x][i]=fa[fa[x][i-1]][i-1];
for(int i=head[x];i;i=nxt[i])
if(t[i]!=f)dfs(t[i],x);
}//预处理father
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 k=lg[dep[x]]-1;k>=0;k--)
if(fa[x][k]!=fa[y][k])x=fa[x][k],y=fa[y][k];
return fa[x][0];
}//LCA
int dist(int x,int y){
int z=lca(x,y);
return dep[x]+dep[y]-dep[z]*2;
}//x、y两点之间的距离
bool check(int x,int k){
if(x<=k&&x%2==k%2)return true;
return false;
}//检查长度为x的边是否满足前文讲得2个条件
int main(){
int n;
read(n);
for(int i=1;i<n;i++){
int x,y;
read(x);read(y);
add(x,y);add(y,x);
}
dfs(1,0);
for(int i=1;i<=n;i++)lg[i]=lg[i-1]+(1<<lg[i-1]==i);//预处理除log
int T;
read(T);
while(T--){
int x,y,a,b,k;
read(x);read(y);read(a);read(b);read(k);
int ab=dist(a,b),ax=dist(a,x),yb=dist(b,y),ay=dist(a,y),bx=dist(b,x);//3条边
if(check(ab,k)||check(ax+yb+1,k)||check(ay+bx+1,k))puts("YES");//有1条符合条件,就代表有
else puts("NO");//3条都不符合就代表没有
}
return 0;
}

后记

这道题还是很有思考的价值,也算是积累了经验看到一棵树加 \(1\) 条边,未必一定要往基环树想。希望觉得好的同学可以点赞,有问题请在评论区表述一下,是我的题解都够再完善一下。

题解 CF1304E 【1-Trees and Queries】的更多相关文章

  1. Codechef Dynamic Trees and Queries

    Home » Practice(Hard) » Dynamic Trees and Queries Problem Code: ANUDTQSubmit https://www.codechef.co ...

  2. 题解-------CF1304E 1-Trees and Queries

    传送门 题目大意 给你一棵无根树,然后询问Q次,每次把点$x$和点$y$连接,问你从点$a$到点$b$是否有一条长度为$k$的简单路径,每次询问完后会把新添加的边删除. 思路:树上LCA 题目跟201 ...

  3. 题解-Codeforces917D Stranger Trees

    Problem \(\mathrm{Codeforces~917D}\) 题意概要:一棵 \(n\) 个节点的无向树.问在 \(n\) 个点的完全图中,有多少生成树与原树恰有 \(k\) 条边相同,对 ...

  4. 【题解】Luogu CF817F MEX Queries

    原题传送门 817,我突然想到了某8位质数 这题珂以说是珂朵莉树的模板 三个操作都肥肠简单,前两个区间赋值,第三个区间0变1,1变0 每次输出从头开始扫描就行(我忘了珂朵莉树的性质,竟然还动态维护最左 ...

  5. LeetCode题解之Leaf-Similar Trees

    1.题目描述 2.问题分析 将叶子节点的值放入vector,然后比较. 3.代码 bool leafSimilar(TreeNode* root1, TreeNode* root2) { vector ...

  6. [CodeChef-ANUDTQ] Dynamic Trees and Queries

    类似维护括号序列,给每个点建两个点,然后所有操作都能轻松支持了.注意sum和lastans是long long. #include<cstdio> #include<algorith ...

  7. 题解 CF375D 【Tree and Queries】

    首先,子树上的查询问题可以通过$DFS$序转为序列问题 再一看,没有修改,可以离线,这不就是莫队吗? 我们用$sum_i$表示出现次数$\geq i$的个数 用$val_i$表示第$i$种颜色的出现次 ...

  8. 题解 UVA1479 【Graph and Queries】

    \[ \text{Preface} \] 算是一道思维难度稍易,代码难度稍难的题吧. \[ \text{Description} \] 给出一张 \(n\) 个点,\(m\) 条边的图,点带权.需要支 ...

  9. 题解 CF938G 【Shortest Path Queries】

    题目让我们维护一个连通无向图,边有边权,支持加边删边和询问从\(x\)到\(y\)的异或最短路. 考虑到有删边这样的撤销操作,那么用线段树分治来实现,用线段树来维护询问的时间轴. 将每一条边的出现时间 ...

随机推荐

  1. JAVA如何判断两个字符串是否相等

    ==比较引用,equals 比较值 1.java中字符串的比较:== 我们经常习惯性的写上if(str1==str2),这种写法在java中可能会带来问题 example1: String a=&qu ...

  2. Jun

    Contents 数据来源 代码演示 讨论 一.数据来源 为了节省时间,我直接用了官方所给的数据,分别是雄性和雌性小鼠的肝脏芯片数据 Female Data Male Data 二.代码演示 数据输入 ...

  3. 使用TensorFlow训练自己的语音识别AI

    这次来训练一个基于CNN的语音识别模型.训练完成后,我们将尝试将此模型用于Hotword detection. 人类是怎样听懂一句话的呢?以汉语为例,当听到"wo shi"的录音时 ...

  4. Java中的成员内部类

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.java * 作者:常轩 * 微信公众号:Worldh ...

  5. Web Scraper 高级用法——抓取属性信息 | 简易数据分析 16

    这是简易数据分析系列的第 16 篇文章. 这期课程我们讲一个用的较少的 Web Scraper 功能--抓取属性信息. 网页在展示信息的时候,除了我们看到的内容,其实还有很多隐藏的信息.我们拿豆瓣电影 ...

  6. JZOJ 3928. 【NOIP2014模拟11.6】射击

    3928. [NOIP2014模拟11.6]射击 (Standard IO) Time Limits: 1000 ms Memory Limits: 65536 KB Description 有问题, ...

  7. 初窥构建之法——记2020BUAA软工个人博客作业

    项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任建) 这个作业的要求在哪里 个人博客作业 我在这个课程的目标是 完成一次完整的软件开发经历并以博客的方式记录开发过程的心得掌握 ...

  8. Js逆向-滑动验证码图片还原

    本文列举两个例子:某象和某验的滑动验证 一.某验:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s 未还原图像: 还原后的图: ...

  9. 基于GIS空间分析的多边形提取技术

    现有基于矢量图形的骨架线提取方法主要包括数据预处理.基于约束 Delauny 三角剖分的骨架线结点生成和骨架线的连接 3 个过程,上述过程都可利用现有 GIS 系统的数据处理.空间分析和建模功能实现. ...

  10. 026.掌握Service-外部访问

    一 集群外部访问 由于Pod和Service都是Kubernetes集群范围内的虚拟概念,所以集群外的客户端默认情况,无法通过Pod的IP地址或者Service的虚拟IP地址:虚拟端口号进行访问.通常 ...