题目描述
Description
你有两棵有根树,每棵各有n 个顶点。让我们用整数1到n给每棵树的顶点编号。两棵树的根都是顶点1。第一棵树的边都染成蓝色,第二棵树的边都染成红色。简明起见,我们称第一棵树是蓝色的,以及第二棵树是红色的。
同时满足下面的两个条件下,边(x, y) 有害于边(p,q):
1. 边(x,y)的颜色不同于边(p,q)。
2. 考虑与边(p, q) 颜色相同的树,编号为x, y 的两个顶点中恰好有且只有一个同时在顶点p 的子树与顶点q 的子树里。
在这个问题里,你的任务是模拟下述过程。此过程由若干阶段组成:
1. 在同一个阶段中删除的边颜色相同。
2. 在第一阶段,删除恰好一条蓝色的边。
3. 假设在阶段i 我们删去了边(u1,v1), (u2,v2),... , (uk,vk)。那么在阶段i+1我们要删去有害于(u1,v1) 的边,然后删去有害于(u2,v2) 的边,接着继续删到删完有害于(uk,vk) 的边。
对于每个阶段,求解哪些边将在这个阶段中被删除。注意,有害边的定义只依赖于开始删边之前的初始就拥有的两棵有根树。
Input
输入第一行为整数n(2<=n<=2*10^5)——两棵树分别有的顶点数目。
接下来的一行包含n-1个正整数a2,a3,...,an(1<=ai<=n;ai<>i),描述第一棵树的边。数字ai意味着第一棵树有一条边连接顶点ai和顶点i。
接下来的又一行包含n-1个正整数b2,b3,...,bn(1<=bi<=n;bi<>i),描述第二棵树的边。数字ai意味着第二棵树有一条边连接顶点bi和顶点i。
接下来的再一行包含一个整数idx(1 <=idx < n)表示在第一阶段中删除的边的编号。我们让每棵树的每条边按照他们在输入中的前后顺序从1 到n-1 编号。
Output
对于每个阶段输出两行。如果这个阶段删除的边是蓝色的,那么对应这一阶段的两行中,第一行必须为单词Blue,否则为单词Red。对应的第二行包含所有此阶段删除的边的编号,按数字递增顺序输出。
Sample Input
5
1 1 1 1
4 2 1 1
3
Sample Output
Blue
3
Red
1 3
Blue
1 2
Red
2
Data Constraint
30% 的数据,n<=100。
60% 的数据,n<=1000。
简明起见,我们假设有根树中的边都是有向的,并且从顶点1 可以到达所有顶点。那么,顶点v 的子树就是顶点v (在前面得到的有向图中)能到达的点组成的点集(顶点v 也包括在这个集合中)。
题解
好像有树套树的神奇做法?但是一个log都会被卡
一条路径u-v经过一条边x-y(fa[y]=x),等价与子树y内只有一个该路径中的端点,即 所以对两棵树分别搞出bg和ed,把一条边挂在另一棵树上 把边按bg[y]从小到大/按bg[x]从大到小排序,然后按bg[x]/bg[y]为关键字插在线段树里,按顺序用vector存 那么一次要删掉的边只能是不在[x,y]区间里的,所以从后往前删即可 一个小优化: 如果把[u,v](u为关键字)插到区间[l,r]里,则必须保证v不在[l,r]里,否则没有意义 因为查找的区间[x,y]必然包含[l,r],若v在[l,r]里则必在[x,y]中,那么v不会被删掉
min(bg[u],bg[v])
bg[y]<=min(bg[u],bg[v])<=ed[y],ed[y]code
c++的优越性#include