入门树形结构详解&&洛谷P5836题解

本文深入解析树形结构在算法中的应用,重点介绍倍增优化LCA、树上前缀和与树上差分等技术,并通过具体题目实战演示如何运用这些技术解决问题。

前言

本题之所以被用于"入门树形结构详解",是因为AC本题需要下面几个前置芝士:

①倍增优化LCA;

②树上前缀和;

③树上差分。

本篇文章适合树形结构初学者阅读。讲得详细的程度远远超过您的想象!

题面

题目描述

Farmer John 计划建造 N个农场,用 N-1条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。

Farmer John 的 MM 个朋友经常前来拜访他。在朋友 ii 拜访之时,Farmer John 会与他的朋友沿着从农场Ai到农场Bi的唯一路径行走(有可能出现Ai=Bi的情况)。除此之外,他的朋友们还可以品尝他们经过的路径上任意一头奶牛的牛奶。由于 Farmer John 的朋友们大多数也是农场主,所以他们对牛奶有着极强的偏好。有些朋友只喝更赛牛的牛奶,其余的只喝荷斯坦牛的牛奶。任何 Farmer John 的朋友只有在他们访问时能喝到他们偏好的牛奶才会高兴。

请求出每个朋友在拜访过后是否会高兴。如果高兴输出0,否则输出1,详见输出格式。

输入输出格式

输入格式

输入的第一行包含两个整数N和M。

第二行包含一个长为 N的字符串。如果第 i个农场中的奶牛是更赛牛,则字符串中第i个字符为G,如果第 i个农场中的奶牛是荷斯坦牛则为H。

以下 N-1行,每行包含两个不同的整数X和Y,表示农场 X与Y之间有一条道路。

以下M行,每行包含整数Ai, Bi和一个字符Ci,表示朋友i摆放时从Ai走到Bi(沿着唯一路径行走),且他喜欢喝的牛奶的种类。

输出格式
输出一个长为M的二进制字符串。如果第i个朋友会感到高兴,则字符串的第i个字符为1;否则为0。

样例数据

Input:
5 5
HHGHG
1 2
2 3
2 4
1 5
1 4 H
1 4 G
1 3 G
1 3 H
5 5 H

Output:
10110

数据范围

共有12个测试点,各测试点均分。

第一个测试点: 与样例相同;

第2~5个测试点: N≤103N≤10^3N103, M≤2×103M≤2×10^3M2×103

对于100%的数据满足,1≤N,M≤1051≤N, M≤10^51N,M105

样例解释

在这里,从农场 1 到农场 4 的路径包括农场 1、2 和 4。所有这些农场里都是荷斯坦牛,所以第一个朋友会感到满意,而第二个朋友不会。

解法

首先,显而易见地发现,节点u到节点v的唯一路径为u→LCA(u,v)→v,其中LCA(u,v)表示u与v的最近公共祖先。

所以,我们只需要找到LCA(u,v),并判断这条路径是否存在H或G即可。但是我们不能把这条路走一遍,而要使用树上前缀和与树上差分来优化这个过程。

树上前缀和

为了表述方便,设1号节点为根节点(设任何一个节点为根节点都行,不会影响答案的正确性)

树上前缀和与一维前缀和类似,但是本题中有两个参数,即从该节点到1号根节点的H的数量与G的数量。所以,这里的前缀和表示为pre[i].h与pre[i].g,其中pre[i].h表示从i号节点到1号节点的H的数量,pre[i].g表示从i号节点到1号节点的G的数量。

递推十分显然,dfs即可,这里不再详细论述。

然后,也容易发现,从i号节点到j号节点(i的深度比j的深度小)的H的数量为dp[j].h-dp[father[i]].h,G的数量同理;这里father[i]表示i的父节点。如果不懂可以画图或拿一维前缀和来类比一下,就能瞬间明白。

这下思路就很清晰啦。剩下的就是对码力的考验,但我对自己的码力是很有自信的。

萌新福利

相信看这篇博客的都是与我一样的普及组的小萌新——如果阁下不是,请接收我的orz并跳过此"详细讲解"。

①定义

int n,q,u,v,cnt=0;//n为节点数,q为询问数 
int head
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值