[Luogu 3398] 仓鼠找sugar
[Luogu 3398] 仓鼠找sugar
又是 LCA…
前两天死活写不过的一个题今天终于顺手切了。
思路嘛参考了一楼题解。
就是说,对于 a, b, c, d 四个点,
令 x = LCA(a, b), y = LCA(c, d),
两条路径有交叉,当且仅当 c, d 至少一个在 x 的子树下,且 a, b 至少一个在 y 的子树下。
由于我是 HLD 求的 LCA,第一遍 DFS 时顺手把子树大小求了,后边判断在不在一棵子属下的时候就可以很方便了。
就这样。
#include <algorithm>
#include <cstdio>
const int MAXN = 100010;
int n, q;
struct Graph
{
struct Edge
{
int to;
Edge *next;
Edge(int to, Edge* next): to(to), next(next) {}
~Edge(void)
{
if(next != NULL)
delete next;
}
}*head[MAXN];
Graph(int n)
{
std :: fill(head + 1, head + n + 1, (Edge*)NULL);
}
~Graph(void)
{
for(int i = 1; i <= n; ++i)
delete head[i];
}
void AddEdges(int u, int v)
{
head[u] = new Edge(v, head[u]);
head[v] = new Edge(u, head[v]);
}
}*G;
namespace HLD
{
int num;
struct Node
{
int depth, father, son, top, size, DFN;
}s[MAXN];
void DFS1(int u, int k)
{
s[u].depth = k;
s[u].size = 1;
int v;
for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)
if(!s[v = i -> to].size)
{
DFS1(v, k + 1);
s[u].size += s[v].size;
s[v].father = u;
if(s[v].size > s[s[u].son].size)
s[u].son = v;
}
}
void DFS2(int u, int top)
{
s[u].top = top;
s[u].DFN = ++num;
if(s[u].son)
DFS2(s[u].son, top);
int v;
for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)
if(!s[v = i -> to].DFN)
DFS2(v, v);
}
void Init(void)
{
DFS1(1, 1);
DFS2(1, 1);
}
int LCA(int x, int y)
{
int a, b;
while((a = s[x].top) ^ (b = s[y].top))
if(s[a].depth > s[b].depth)
x = s[a].father;
else
y = s[b].father;
return s[x].depth < s[y].depth ? x : y;
}
bool Range(int x, int y)
{
return s[x].DFN <= s[y].DFN && s[y].DFN < s[x].DFN + s[x].size;
}
bool Query(int a, int b, int c, int d)
{
int x = LCA(a, b), y = LCA(c, d);
return (Range(x, c) || Range(x, d)) && (Range(y, a) || Range(y, b));
}
}
int main(void)
{
scanf("%d %d", &n, &q);
G = new Graph(n);
for(int i = 1, u, v; i < n; ++i)
{
scanf("%d %d", &u, &v);
G -> AddEdges(u, v);
}
HLD :: Init();
for(int i = 1, a, b, c, d; i <= q; ++i)
{
scanf("%d %d %d %d", &a, &b, &c, &d);
puts(HLD :: Query(a, b, c, d) ? "Y" : "N");
}
return 0;
}
谢谢阅读。
[Luogu 3398] 仓鼠找sugar的更多相关文章
- Luogu P3412 仓鼠找$sugar$ $II$
Luogu P3412 仓鼠找\(sugar\) \(II\) 题目大意: 给定一棵\(n\)个点的树, 仓鼠每次移动都会等概率选择一个与当前点相邻的点,并移动到此点. 现在随机生成一个起点.一个终点 ...
- luogu P3412 仓鼠找sugar II 期望 树形dp
LINK:仓鼠找sugar II 以前做过类似的期望题目 加上最后的树形dp不算太难 还是可以推出来的. 容易发现 当固定起点和终点的时候 可以先固定根 这样就不用分到底是正着走还是倒着走了. 1为根 ...
- luogu P3398 仓鼠找sugar [LCA]
题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...
- 【luogu P3398 仓鼠找sugar】 题解
题目链接:https://www.luogu.org/problemnew/show/P3398 辣鸡树剖1300ms 倍增大法吼啊 #include <cstdio> #include ...
- 洛谷 3398 仓鼠找sugar——树链剖分
题目:https://www.luogu.org/problemnew/show/P3398 原来只要把值记录成第几次就行了. 别忘了while(top[a]!=top[b])之后还要走一步. #in ...
- Luogu P3398 仓鼠找sugar
这还是一道比较好的树剖题(去你的树剖,LCA即可) 这里主要讲两种思路,其实都是很基本也很经典的 1 树链剖分 还是先讲一下这种算法吧,虽然写起来很烦(不过感觉写多了就习惯了,而且还有一种莫名的快感) ...
- 洛谷 3398 仓鼠找sugar 【模板】判断树上两链有交
[题解] 题意就是判断树上两条链是否有交.口诀是“判有交,此链有彼祖”.即其中一条链的端点的Lca在另一条链上. 我们设两条链的端点的Lca中深度较大的为L2,对L2与另一条链的两个端点分别求Lca, ...
- 【树链剖分/倍增模板】【洛谷】3398:仓鼠找sugar
P3398 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...
- 洛谷P3398 仓鼠找sugar [LCA]
题目传送门 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...
随机推荐
- Android笔记-1
1.点击按钮出现小窗口(响应事件) 配置方式: Activity_main.xml文件中:<Button (输入)android: onClick=”test1” /> MainActiv ...
- visualStudo编译c程序, 提示函数unSafe问题
问题描述: 在利用visualStudo进行C语言编程时,若C语言源程序中有print,freopen等函数时,IDE软件总是unSafe,而且无法通过编译. 解决方案: 在<视图>中找到 ...
- JS学习:JavaScript的核心
分享到 分类 JS学习 发布 ourjs 2013-12-02 注意 转载须保留原文链接,译文链接,作者译者等信息. 作者: JeremyWei 原文: JavaScript The ...
- AngularJs 学习 (一)
最近学习了一下关于AngularJs的知识,发现和Vue还是有非常相似的东西.所以对于学过Vue的自己来说,还是比较好理解的 特点:双向数据绑定,单页面应用 控制器: AngularJs控制器可以控制 ...
- KEIL C51程序中如何嵌入汇编
模块内接口:使用如下标志符:#pragma asm汇编语句#pragma endasm注意:如果在c51程序中使用了汇编语言,注意在Keil编译器中需要激活Properties中的“Generate ...
- Alpha阶段事后诸葛分析
一.设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件主要是解决在宿舍中购买商品的软件,不同于淘宝等软件,本软件主要是用于学生开设的店铺及宿 ...
- 很有用的高级 Git 命令
10 个很有用的高级 Git 命令 迄今,我已经使用Git很长一段时间了,考虑分享一些不管你是团队开发还是个人项目,都受用的高级git命令. 1. 输出最后一次提交的改变 这个命令,我经常使用它 来发 ...
- 《统计学习方法》P179页10.22前向后向算法公式推导
- springboot学习笔记-2 一些常用的配置以及整合mybatis
一.一些常用的配置 1.1 使用没有父POM的springboot 通过添加scope=import的依赖,仍然能获取到依赖管理的好处: <dependencyManagement> &l ...
- BZOJ3481 DZY Loves Math III(数论+Pollard_Rho)
考虑对于每一个x有多少个合法解.得到ax+by=c形式的方程.如果gcd(x,y)|c,则a在0~y-1范围内的解的个数为gcd(x,y).也就是说现在所要求的是Σ[gcd(x,P)|Q]*gcd(x ...