动态连通块
题号:NC22578
时间限制:C/C++/Rust/Pascal 2秒,其他语言4秒
空间限制:C/C++/Rust/Pascal 512 M,其他语言1024 M
64bit IO Format: %lld

题目描述

小T有n个点,每个点可能是黑色的,可能是白色的。
小T对这张图的定义了白连通块和黑连通块:
白连通块:图中一个点集V,若满足所有点都是白点,并且V中任意两点都可以只经过V中的点互相到达,则称V中的点构成了一个白连通块。
黑连通块:类似白连通块的定义。
小T对这n个点m次操作。
1、在两个点之间连一条边。
2、询问白(黑)连通块个数。
3、给出x,y两个点,保证同色(为了方便描述,x,y都是白点,黑色同理)。询问存在多少个黑点,将它改变颜色后,x,y所在的白连通块会合并为一个。如果x,y已经在一个白连通块内了,输出-1。(注意:这里不会对点的颜色改变,只统计个数)


输入描述:

第一行两个整数n,m,分别表示点的个数和操作的个数。
第二行n个整数,第i个整数描述第i个点的颜色,0表示白色,1表示黑色。
接下来m行,每行包含2个或者3个整数,描述三种操作。
操作1:1,x,y,表示在x,y之间加入一条边。
操作2:2,x,若x=0,询问白连通块的个数,否则询问黑连通块的个数。
操作3:3,x,y,表示第三种操作。

输出描述:

对于询问操作,输出一个整数。
示例1

输入

复制
6 7
0 1 0 0 0 1
1 3 2
1 2 4
3 3 4
1 1 3
2 0
3 1 4
3 1 3

输出

复制
1
3
1
-1

说明

第一次询问:2号点变成白色后,3,4所在的白连通块合并为一个。
第二次询问:白连通块的个数为3,分别是{1,2},{3},{4}。
第三次询问:2号点变成白色后,1,4所在的白连通块合并为一个。
第四次询问:1,3已经是同一个白连通块了,输出-1。