【SDOI2011】染色
【题目描述】
给定一棵有n个节点的无根树和m个操作,操作有2类:
1、将节点a到节点b路径上所有点都染成颜色c;
2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。
请你写一个程序依次完成这m个操作。
【输入】
第一行包含2个整数n和m,分别表示节点数和操作数;
第二行包含n个正整数表示n个节点的初始颜色
下面n-1行每行包含两个整数 和 ,表示x和y之间有一条无向边。
下面m行每行描述一个操作:
“C a b c”表示这是一个染色操作,把节点a到节点b路径上所有点(包括a和b)都染成颜色c;
“Q a b”表示这是一个询问操作,询问节点a到节点b(包括a和b)路径上的颜色段数量。
【输出】
对于每个询问操作,输出一行答案。
【输入样例】
6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
【输出样例】
3
1
2
【数据范围】
N<=10^5,操作数M<=10^5,所有的颜色C为整数且在[0, 10^9]之间。
【题解】
树链剖分妥妥的,但这类题的难度似乎都在如何维护线段树上= =
对这棵树进行重链剖分映射到线段树中,为了维护方便,线段树内额外记录三个值:区间颜色段数、区间最左端和最右端颜色。更新的操作就和普通的线段树一样,在树上按重链一段一段处理就好。
接下来是处理询问,每一段上的询问处理好后应该跳到下一段,这时候判断这一段重链的top和fa[top]颜色是否相等,如果相等答案-1即可。注意这两个结点颜色的询问方式,应该单点查询(或者就用区间查询,区间是单点),而不能直接查询最开始记录的颜色数组(听起来觉得不会这么逗,但本蒟蒻在此WA无数)。
【代码】
就是这样,然后使劲写代码就好。