Question:
Link: Click to open the link
Question:
There are n blocks, ranging from 1 to n. Perform some operations P times. M: x y puts x blocks on Y. If X and Y are equal, ignore them. C: X calculates the number of blocks under X blocks.
Ideas:
For questions with weights and query sets, the defined array sum [I] indicates the number of blocks under the I blocks. When M is encountered, X and Y are merged into the same set. We regard each node as one pile, where rank [I] indicates the number of blocks at each pile,Initially, there are n piles, and each pile contains one block. Therefore, the initial value of rank [] should be 1.
Code:
# Include <iostream> # include <cstdio> # include <cstring> using namespace STD; const int n = 30030; int root [N]; int sum [N], rank [N]; int Q; int findset (int x) {If (x = root [x]) return X; int temp = findset (root [x]); sum [x] + = sum [root [x]; return root [x] = temp;} void mergeset (int x, int y) {int FX = findset (x); int FY = findset (y); If (FX = FY) return; root [FX] = FY; sum [FX] + = rank [FY]; // sum rank [FY] + = Ra NK [FX]; // The rank value must be updated for each M operation .} Void Init () {for (INT I = 0; I <= 30000; I ++) {root [I] = I; rank [I] = 1; sum [I] = 0 ;}} int main () {// freopen ("input.txt", "r", stdin); char ch; int x, y, z; while (scanf ("% d", & Q )! = EOF) {Init (); getchar (); While (Q --) {scanf ("% C", & Ch); getchar (); if (CH = 'M') {scanf ("% d", & X, & Y); mergeset (x, y );} else {scanf ("% d", & Z); findset (z); printf ("% d \ n", sum [Z]) ;}getchar ();}} return 0 ;}---------------------------------------------------------------
Fighting, never shrinking; fighting, never stopping ~~~~~~~~