OI技术宅

Tech Otakus save the world!
Welcome,my dear friends!
【I'm kiana/kiana810@126.com】

【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无数)。

【代码】

就是这样,然后使劲写代码就好。

http://paste.ubuntu.com/7224121/

评论

© OI技术宅 | Powered by LOFTER