problem Description
John is playing with blocks. There is N blocks (1300001 do some operations P times (11000000 in the for each C operation.
Input
The first line contains integer P. Then P lines follow, each of the which contain an operation describe above.
Output
for in one line.
Sample Input
6161 2 426 3 4
Sample Output
1 0 2
Source
multi-university Training Contest 1-host by Tju
The main topic: there are n piles (ordinal number), there are two actions at a time:
M x y means to move all the stacks where x resides to the pile where y is.
C x Ask How many squares there are under X
Workaround: Use the Count[x (path compression) implementation, and then use "x" to indicate the total number of piles of the heap in which it is located ,Under[x] represents the number of piles under X .
First, each operation we merge two sets (if the original is in the same set except),Count[x] is a direct implementation of each operation , is to add the number of two heaps, it is easy (the initial value is 1). So when a move occurs, first determine the bottom x of the heap where x is located, and y at the bottom of the heap y , then the number of under[x] is the sum of the other piles of piles count[y], With this condition, in the next operation, you can search for the root and update other unknown under[x according to find (x) .
1#include <iostream>2#include <cstdio>3#include <cstring>4 using namespacestd;5 #defineN 300066 intFa[n];7 intUnder[n];//the number below8 intCnt[n];//number of heaps in the heap9 voidinit () {Ten for(intI=0; i<n;i++){ Onefa[i]=i; Aunder[i]=0; -cnt[i]=1; - } the } - intFindintson) { - if(fa[son]!=son) { - intt=find (Fa[son]); +under[son]+=Under[fa[son]]; -fa[son]=T; + } A returnFa[son]; at //return Fa[x]==x?x:fa[x]=find (Fa[x]); - } - voidMergeintXinty) { - introot1=find (x); - intRoot2=find (y); - if(ROOT1==ROOT2)return; inunder[root1]=Cnt[root2]; -cnt[root2]+=CNT[ROOT1]; tofa[root1]=Root2; + } - intMain () the { * intN; $ while(SCANF ("%d", &n) = =1){Panax Notoginseng init (); - Chars[3]; the intx, y; + for(intI=0; i<n;i++){ Ascanf"%s", s); the if(s[0]=='M'){ +scanf"%d%d",&x,&y); - merge (x, y); $ } $ Else{ -scanf"%d",&x); - find (x); theprintf"%d\n", under[x]); - }Wuyi } the } - return 0; Wu}View Code
Recommend
Hdu 2818 Building Block (with right and check set, very beautiful topic)