Building Block
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3081 Accepted Submission(s): 935
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.
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
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
Sample Output
1 0 2解题思路:题意是对于T行输入有两种操作。如果是M操作,那么把a处的方块全部移到和b处的上方,。如果是C操作,那么询问key下面有多少个方块。每堆的方块初始值为1。开sum数组记录以i为根的树总共有多少方块,开cnt数组记录i下面有多少方块,开f数组记录集合关系。unin操作时代码作修改,如果遇到两个点的祖先不相等,在重新认完祖先后,还要对其sum和cnt进行修改。以x和y为例,如果把x放到y上方,当f[fx] = fy后,那么原来x堆最底下那个结点的后继为0,现在连完后,x节点下方变成了sum[y]个方块,同时对于y点来说它本身总的方块数量增加了sum[x]。find函数查找时更新cnt的值·····(why?·····)完整代码:#include <functional> #include <algorithm> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <climits> #include <cassert> #include <complex> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") typedef long long LL; typedef double DB; typedef unsigned uint; typedef unsigned long long uLL; /** Constant List .. **/ //{ const int MOD = int(1e9)+7; const int INF = 0x3f3f3f3f; const LL INFF = 0x3f3f3f3f3f3f3f3fLL; const DB EPS = 1e-9; const DB OO = 1e20; const DB PI = acos(-1.0); //M_PI; char str[3]; const int maxn = 50001; int f[maxn]; int sum[maxn]; int cnt[maxn]; void init() { memset(cnt , 0 , sizeof(cnt)); for(int i = 0 ; i <= maxn ; i ++) { f[i] = i; sum[i] = 1; } } int find(int x) { if(x == f[x]) return f[x]; int t = find(f[x]); cnt[x] += cnt[f[x]]; return f[x] = t; } void unin(int a , int b) { int x = find(a); int y = find(b); if(x == y) return ; f[x] = y; cnt[x] = sum[y]; sum[y] += sum[x]; } int main() { #ifdef DoubleQ freopen("in.txt","r",stdin); #endif int T; scanf("%d",&T); init(); while(T--) { scanf("%s",str); if(str[0] == 'M') { int a , b; scanf("%d%d",&a,&b); unin(a , b); } else if(str[0] == 'C') { int key; scanf("%d",&key); find(key); printf("%d\n",cnt[key]); } } }