洛谷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 ...
随机推荐
- 【学习总结】GirlsInAI ML-diary 总
2019-1-7 GirlsInAI第一期: 人工智障工程师养成计划,代号ML-diary 原博github链接:Girls-In-AI 环境:Windows / MacOS 工具:Anaconda ...
- ABP新增模块可能遇到的问题
当我们新增一个模块时: public class SSORedisModule: AbpModule { //public override void PreInitialize() //{ // b ...
- iOS 利用高德地图WMS服务
Demo: https://github.com/xushiyou23/AMapTesting 转: 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net ...
- python之装饰器初识
一.@abstractmethod 1.抽象类的作用:规范编程模式 多人开发.复杂的需求.后期的扩展 是一种用来帮助我们完成规范化的手段 2.如何定义抽象类 1,from abc import ABC ...
- eclipse安装Activiti
一. eclipse自己下载 打开eclipse软件,然后点击菜单栏的help选项,选择install New Software,示例如下: 出现如下对话框: 点击添加[Add]按钮,出现如下对话框 ...
- mpvue——引入vant_weapp组件
克隆仓库 克隆后,将dist目录下的所有文件复制到项目中的/static/vant/目录下,vant目录是我自己创建为了区分的 git clone https://github.com/youzan/ ...
- mpvue——页面跳转
两个页面 两个页面的跳转,只是单纯的A->B这种跳转. 组件 直接使用小程序的组件,navigator,里面还有一些其他的参数,大家可以自行翻阅官方文档 <navigator url=&q ...
- [模板]快速傅里叶变换(FFT)
Miskcoo大佬的多项式全家桶传送门 rvalue大佬的FFT讲解传送门 用途 将多项式快速(nlogn)变成点值表达,或将点值表达快速变回系数表达(逆变换),(多数时候)来达到求卷积的目的 做法 ...
- 这可能是最为详细的Docker入门吐血总结
这可能是最为详细的Docker入门吐血总结 https://www.cnblogs.com/ECJTUACM-873284962/p/9789130.html Docker是什么? 在计算机技术日新 ...
- os.listdir()、os.walk()和os.mkdir()的用法
内容主要参照博客https://blog.csdn.net/xxn_723911/article/details/78795033 http://www.runoob.com/python/os-wa ...