洛谷P3398 仓鼠找suger
传送门啦
思路:
那么从 $ A $ 到 $ B $ 可以分解成 先从 $ A $ 到 $ X $ 再从 $ X $ 到 $ B $ 。。。 另一个同理
假设能相遇 那么
要么在 $ A $ 到 $ X $ 的过程 $ A,B $ 相遇 要么在 $ X $ 到 $ B $ 的过程 $ A,B $ 相遇
对于在 $ A $ 到 $ X $ 的过程相遇的情况 又可以分解为:
情况1:
在 $ A $ 到 $ X $ 的过程和 $ C $ 到 $ Y $ 的过程 中 $ A,B $ 相遇
情况2:
在 $ A $ 到 $ X $ 的过程和 $ Y $ 到 $ D $ 的过程 中 $ A,B $ 相遇
呃呃呃。。。
相遇的情况 :
$ a->X , c->Y $ 相遇(可以认为 松鼠和他基友都在网上冲)
$ a->X,Y->d $ 相遇(一个往上冲,一个在往下冲)
$ X->b,c->Y $ 相遇(一个往下冲 一个往上冲)
$ X->b,Y->d $ 相遇(都往下冲)
根据树中的每一个节点的父亲都是唯一的, $ lca $ 可以认为是他们最短路径上深度最浅的那个点, $ a,b,c,d $ 到他们 $ lca $ 的路径是唯一的。
而上述的 $ 4 $ 个 $ lca $ 中深度最大的那一个 我们姑且记为 $ S $ ,那么 $ S $ 一定是 $ a,b $ 中的一个和 $ c,d $ 的一个的 $ lca $ (我们假设是 $ lca(a,d) $ )
那么如果 $ S $ 的深度大于 $ x,y $ 中较大的的那一个,说明 $ a $ 在和 $ d $ 在往上冲的过程中一定要经过他们的 $ lca $ ,也就是 $ S $ ,再经过 $ x $ 或者是 $ y $ 。因为 $ a $ 和 $ d $ 是 $ a,b $ 中的一个和 $ c,d $ 中的一个,他们还要冲向 $ X $ 或者是 $ Y $ 。这种情况必然相遇;
在 $ X 、Y $ 中取一个最大,再在 $ lca(a,c).lca(a,d),lca(b,c),lca(b,d) $ 这四个当中取一个最大,如果后者的深度大于等于前者,那么可以相遇,否则不能;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define re register
using namespace std ;
const int maxn = 5 * 1e5 + 4 ;
inline int read () {
int f = 1 , x = 0 ;
char ch = getchar () ;
while (ch > '9' || ch < '0') {if(ch == '-') f = -1 ; ch = getchar () ;}
while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0' ; ch = getchar () ;}
return x * f ;
}
int n , q , u , v , a , b , c , d ;
int head[maxn] , tot ;
struct Edge {
int from , to , next ;
}edge[maxn << 1] ;
inline void add (int u , int v) {
edge[++tot].from = u ;
edge[tot].to = v ;
edge[tot].next = head[u] ;
head[u] = tot ;
}
int dep[maxn] , f[maxn][21] ;
inline void dfs (int x , int fa) {
dep[x] = dep[fa] + 1 ;
f[x][0] = fa ;
for(re int i = 1 ; (1 << i) <= dep[x] ; ++ i) {
f[x][i] = f[f[x][i - 1]][i - 1] ;
}
for(re int i = head[x] ; i ; i = edge[i].next) {
int v = edge[i].to ;
if(v != fa) dfs(v , x) ;
}
}
inline int lca (int a , int b) {
if(dep[a] < dep[b]) swap(a , b) ;
for(re int i = 18 ; i >= 0 ; -- i) {
if((1 << i) <= (dep[a] - dep[b])) {
a = f[a][i] ;
}
}
if(a == b) return a ;
for(re int i = 18 ; i >= 0 ; -- i) {
if((1 << i) <= dep[a] && f[a][i] != f[b][i]) {
a = f[a][i] ;
b = f[b][i] ;
}
}
return f[a][0] ;
}
int main () {
n = read () ; q = read () ;
for(re int i = 1 ; i <= n - 1 ; ++ i) {
u = read () ; v = read () ;
add(u , v) ;
add(v , u) ;
}
dfs(1 , 1) ;
for(re int i = 1 ; i <= q ; ++ i) {
a = read () ; b = read () ; c = read () ; d = read () ;
int fm1 = max(dep[lca(a , b)] , dep[lca(c , d)]) ;
int fm2 = max(max(dep[lca(a , c)] , dep[lca(a , d)]) , max(dep[lca(b , c)] , dep[lca(b , d)])) ;
if(fm2 >= fm1)
printf("Y\n");
else
printf("N\n");
}
return 0 ;
}
洛谷P3398 仓鼠找suger的更多相关文章
- 洛谷p3398仓鼠找suger题解
我现在爱死树链剖分了 题目 具体分析的话在洛谷blog里 这里只是想放一下改完之后的代码 多了一个son数组少了一个for 少了找size最大的儿子的for #include <cstdio&g ...
- 洛谷 P3398 仓鼠找sugar 解题报告
P3398 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...
- 洛谷P3398 仓鼠找sugar [LCA]
题目传送门 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...
- 洛谷P3398 仓鼠找sugar
题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...
- 洛谷 P3398 仓鼠找sugar —— 树链剖分
题目:https://www.luogu.org/problemnew/show/P3398 树链剖分一下,路径就变成线段树上的几个区间: 两条路径相交就是线段树上有区间相交,所以在相应位置打个标记, ...
- 洛谷——P3398 仓鼠找sugar
https://www.luogu.org/problem/show?pid=3398#sub 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴 ...
- 洛谷 P3398 仓鼠找sugar 题解
每日一题 day44 打卡 Analysis 首先有一个结论:先找 p1=(a,b),p2=(c,d) 的LCA的深度,在与(a,c),(a,d),(b,c),(b,d)中最深的LCA n的深度比较, ...
- 洛谷 [P3398] 仓鼠找sugar
树剖求LCA 我们可以发现,两条路径ab,cd相交,当且仅当 dep[lca(a,b)]>=dep[lca(c,d)]&(lca(lca(a,b),c)==lca(a,b)||lca(l ...
- 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)
洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...
随机推荐
- Nginx部署静态页
简答说一下如何用Nginx部署静态网页,并绑定域名访问 1.通过FTP上传静态页到服务器指定目录 2.编写nginx的.conf文件 3.重启nginx 如图,这是centos上传文件路径 nginx ...
- openstack搭建之-创建实例(13)
一. 创建flat网络的实例 #运行admin环境变量,创建网络类型为flat . admin-openrc openstack network create --share \ --provider ...
- python基础概念(转)
基础回顾: 1.集合 集合有2个重要作用:关系测试(并集,差集,交集)和去重. 2.文件编码 2.7上默认文件编码是ASCII码,因为不支持中文,就出了GB2312,在2.7上要支持中文就必须申明文件 ...
- Flutter之List
void listDemo() { // 1.list的创建 listCreate(); // 2.多种类型的输出 listPrint(); // 3.添加数据 listAddElement(); / ...
- 【转】深入分析 Parquet 列式存储格式
Parquet 是面向分析型业务的列式存储格式,由 Twitter 和 Cloudera 合作开发,2015 年 5 月从 Apache 的孵化器里毕业成为 Apache 顶级项目,最新的版本是 1. ...
- 不用Ajax时的传参方法
不用Ajax时的怎么传参 创建一个form表单 function test(){ var params = { "参数名": "参数值" }; postExce ...
- rest framework 序列化
serializers 序列化组件 可以实现很轻松的互相转换,最常用的组件 ,用量最大的组件 源码位置 rest_framework.serializers 源码中需要用到的 rest_fram ...
- Forget Guava: 5 Google Libraries Java Developers Should Know
Forget Guava: 5 Google Libraries Java Developers Should Know Published on 2016 7 13 Somenath PandaFo ...
- Docker容器进入的4种方式
Docker容器进入的4种方式 $ sudo docker ps $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 在使用Docker创建了容器之后,大家比较 ...
- (转)Java8内存模型—永久代(PermGen)和元空间(Metaspace)
背景:介绍java8中永久代到元空间的转变. Java8内存模型—永久代(PermGen)和元空间(Metaspace) 一.JVM 内存模型 根据 JVM 规范,JVM 内存共分为虚拟机栈.堆.方法 ...