1 /*
2 * poj-1988 cube stacking. cpp
3 *
4 * created on: 2012-2-12
5 * Author: longdou
6 *
7 * query set:
8 * each node has three fields: 1. Fa [x]: And query the parent node of X in the Set (Fa [x] must be under X, but not necessarily directly adjacent)
9*2. Rank [x]: Number of squares under X (excluding X) and above Fa [x] (including Fa [x ])
10 * (if you directly record the total number of squares under X, you must update
11 * rank field. In this case, the merge operation only needs to update the rank field of the root node of a set,
12 * if you ask "c x" at the same time, you only need to calculate the sum of the rank values from X to the root, with little complexity)
13*3. stacknum [x]: Number of the stack where X is currently located (meaningful only for the root node)
14 *
15 * merge the X and Y sets for each m x Y operation. Update the number of blocks currently contained in each stack.
16 * The findset operation updates the rank field during path compression.
17 *
(In addition, the p81 Example 3 in Liu lujia's black book is similar to this question. The solution is also the same, but it is a little concise ...)
18 */
19 # include <cstdio>
20 using namespace STD;
21
22 const int maxn = 30000 + 10;
23 const int maxp = 100000 + 10;
24
25 int num [maxn] ={}; // number of blocks currently contained in the stack
26 int Fa [maxn], rank [maxn], stacknum [maxn];
27
28 void Init (){
29 for (INT I = 0; I <maxn; I ++ ){
30 num [I] = 1;
31 Fa [I] = I;
32 rank [I] = 0;
33 stacknum [I] = I;
34}
35}
36
37 int findset (int x ){
38 If (x = Fa [x])
39 return X;
40
41 int TMP = Fa [x];
42 Fa [x] = findset (Fa [x]);
43 rank [x] + = rank [TMP]; // update the rank field
44
45 return Fa [x];
46}
47
48 void unionset (int x, int y ){
49 int FX = findset (X );
50 int FY = findset (y );
51
52 If (FX = FY) return;
53
54 Fa [FX] = FY;
55 rank [FX] + = num [stacknum [FY];
56
57 // update the number of blocks currently contained by each stack
58 num [stacknum [FY] + = num [stacknum [FX];
59 num [stacknum [FX] = 0;
60}
61
62 int main (){
63 int P, X, Y;
64 char op;
65
66 Init ();
67
68 scanf ("% d", & P );
69 for (INT I = 0; I <p; I ++ ){
70 getchar ();
71 scanf ("% C", & OP );
72
73 If (OP = 'M '){
74 scanf ("% d", & X, & Y );
75 unionset (x, y );
76}
77 else {
78 scanf ("% d", & X );
79 int FX = findset (X );
80 printf ("% d \ n", rank [x] + rank [FX]);
81}
82}
83
84
85
86 return 0;
87}