Building Block
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 15 Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation: M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command. C X : Count the number of blocks under block X You are request to find out the output for each C operation.
Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
Output
Output the count for each C operations in one line.
Sample Input
6M 1 6C 1M 2 4M 2 6C 3C 4
Sample Output
102
Source
2009 Multi-University Training Contest 1 - Host by TJU
题目大意:第一行输入P, 表示有P个积木和P次操作,编号可能从0~N。
刚开始积木的状态是:每个编号独自算作一个集合。
然后下面有P行,每一行输入操作指令:
M a,b,表示吧包含编号a的集合放在包含编号b集合的上面、
c a,表示询问编号a下面有多少个积木、
解法一:(并查集+压缩路径)
用Count[i]记录以i为根子节点的积木总数,,即为包含编号i的积木总数,记录子节点和父节点。
每次进行M a b操作时:
用A=Find(a),B=Find(b)查找子根节点,且合并子节点。
在去找B的父节点,更新B的父根节点。同时,更新每一个节点上的积木总数。
在进行C a操作时:
查找a的根子节点aa=Find(a),
输出count[aa]-count[a]即为答案、
解法二:
多增加了一个记录状态的数组,Dowm[i]是用来记录i下方有多少个积木。
而且,只需要记录子节点即可。Find(x)用来查找子节点和更新Dowm[]
每次进行M a b操作时:
用A=Find(a),B=Find(b)查找子根节点,且合并子节点。ID[a]=b;
Dowm[a]=Count[b];/*Dowm[a]更新为集合b的数量*/
Count[b]+=Count[a];/*同时,连接两个集合,更新集合总数* /
在进行C a操作时:
只需要调用Find(x)即可更新Dowm[a],输出Dowm[a]即可。
1 #include2 #include 3 #include 4 #include
修改:2015.5.31
1 #include2 #include 3 #include 4 #include