前言
本题之所以被用于"入门树形结构详解",是因为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^3N≤103, M≤2×103M≤2×10^3M≤2×103。
对于100%的数据满足,1≤N,M≤1051≤N, M≤10^51≤N,M≤105。
样例解释
在这里,从农场 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

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





