传送门啦

思路:

那么从 $ 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的更多相关文章

  1. 洛谷p3398仓鼠找suger题解

    我现在爱死树链剖分了 题目 具体分析的话在洛谷blog里 这里只是想放一下改完之后的代码 多了一个son数组少了一个for 少了找size最大的儿子的for #include <cstdio&g ...

  2. 洛谷 P3398 仓鼠找sugar 解题报告

    P3398 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...

  3. 洛谷P3398 仓鼠找sugar [LCA]

    题目传送门 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...

  4. 洛谷P3398 仓鼠找sugar

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  5. 洛谷 P3398 仓鼠找sugar —— 树链剖分

    题目:https://www.luogu.org/problemnew/show/P3398 树链剖分一下,路径就变成线段树上的几个区间: 两条路径相交就是线段树上有区间相交,所以在相应位置打个标记, ...

  6. 洛谷——P3398 仓鼠找sugar

    https://www.luogu.org/problem/show?pid=3398#sub 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴 ...

  7. 洛谷 P3398 仓鼠找sugar 题解

    每日一题 day44 打卡 Analysis 首先有一个结论:先找 p1=(a,b),p2=(c,d) 的LCA的深度,在与(a,c),(a,d),(b,c),(b,d)中最深的LCA n的深度比较, ...

  8. 洛谷 [P3398] 仓鼠找sugar

    树剖求LCA 我们可以发现,两条路径ab,cd相交,当且仅当 dep[lca(a,b)]>=dep[lca(c,d)]&(lca(lca(a,b),c)==lca(a,b)||lca(l ...

  9. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

随机推荐

  1. IDEA设置本地maven仓库

    IDEA设置本地maven仓库 1.下载apache-maven-3.3.9,解压 2.在系统”环境变量“,”系统变量“设置MVN_HOME,如图: 3.在PATH设置,如: %M2_HOME%\bi ...

  2. 搭建Android手机服务器(一)

    自从上学期的软件工程课之后,我们团队设计的抢答器一直想把服务端移到移动端.所以,我一直在考虑如何把手机作为一台服务器.今天我主要讲解一下,对于没有android真机只有模拟器的,如何设置模拟器,使得在 ...

  3. 自定义组件的properties和data

    // components/epsoide/index.js Component({ /** * 组件的属性列表 */ properties: { index: { type: Number //va ...

  4. Python——转义字符解释

    转义字符 解释 ASCII值 \a 响铃 7 \b 退格 8 \f 换页 12 \n 换行 10 \r 回车 13 \t 水平制表 9 \v 垂直制表 11 \\ 一个反斜线字符 92 \' 一个单引 ...

  5. mongoDB 文档操作_删

    mongoDB 文档删除 MySQL对比 mysql delete from table where ... mongo db.collection.deleteOne(query) 删除函数 del ...

  6. 【并发编程】【JDK源码】J.U.C--AQS (AbstractQueuedSynchronizer)(1/2)

    J.U.C实现基础 AQS.非阻塞数据结构和原子变量类(java.util.concurrent.atomic包中的类),concurrent包中的基础类都是使用这种模式来实现的.而concurren ...

  7. [WC2018]通道

    题目描述 http://uoj.ac/problem/347 题解 解法1 求三棵树的直径,看起来非常不可做,但是所有边权都是正的,可以让我们想到爬山. 所以我们可以按照BFS求树的直径的方法,随机一 ...

  8. 前端ajax请求百度地图api

    $.ajax({ type: "get", url: 'http://api.map.baidu.com/place/v2/search', data:{ ak:'您的ak', q ...

  9. jdk各个版本之间的差异

    背景:求职过程中,这个问题反复被问到.如果答不上来,只能说明基本功不扎实,并不能说自己擅长java. 技术趣味史-Java 各个版本的特性 Java 5 2004 年 Sun 公司发布 J2SE5(没 ...

  10. linux18.04下安装的jdk11.0.2

    1.百度搜索jdk,选择jdk11.0.2,操作如下图: 2.下载完成,ctrl+alt+t打开终端并在/usr/local创建java文件夹 cd /usr/local sudo mkdir /us ...