B - 叠叠乐
Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%lld & %llu
Description
Input
Output
Sample Input
Sample Output
Hint
Description
Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations:
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
Input
* Line 1: A single integer, P
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Print the output from each of the count operations in the same order as the input file.
Sample Input
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
Sample Output
1 0 2 解析见代码:
/* poj1988 ,并查集 题目大意:初始时有N块木块,编号1-N,分开放置, 然后对这些木块开始执行P条操作,M a,b是将a所在的 木块堆移到b所在的木块堆上,C a是查询编号为a的木块在 其之下有多少个木块 思路分析:如果查询的是a号木块所在的木块堆一共有多 少堆,那么这道题就是简单的维护下集合内元素数量就可以,但是现在 问的是它下面有多少块,所以还需要维护的就是它下面的木块数目 初始化under[i]=0,然后对于under数组的更新有两个地方,对于 一个子集的根节点(最下面的木块)在merge时就可以更新了,其他 的木块则是要在压缩路径的时候进行更新,under[i]=under[father[i]] 注意一定要先更新后 压缩路径,要不然就没有更新的效果 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> const int maxn=30000+100; int father[maxn]; int sum[maxn]; int under[maxn]; int findroot(int x) { if(x==father[x]) return x; int t=findroot(father[x]); under[x]+=under[father[x]];//先更新under数组,后压缩路径 father[x]=t; return father[x]; } void merge(int a,int b)//根是在下面的木块 { int pa=findroot(a); int pb=findroot(b); if(pa==pb) return; father[pb]=pa; under[pb]=sum[pa]; sum[pa]+=sum[pb]; } int main() { for(int i=1;i<=maxn;i++) { father[i]=i; sum[i]=1; under[i]=0; } int p; scanf("%d",&p); char s[10]; int a,b; while(p--) { scanf("%s",s); if(s[0]=='M') { scanf("%d%d",&a,&b); merge(b,a); } else { scanf("%d",&a); findroot(a);//祖先节点可能发生了 变化 ,因此需要进行更新 printf("%d ",under[a]); } } }