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.
Input
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.
* 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.
Output
* 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.
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 4Sample Output
1 0 2
题意:M a b,将a所在的方块整体移动到b所在的方块上。C a查询a方块下面的方块数。
题解:不能简单的套用并查模板,维护一个数组记录到根距离,在合并·的时候需要不断更新。
还需另开一数组统计a,b所在的方块数。
详细代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int m;
int f[30500];
int deep[30500]; //记录方块到根的距离
int num[30500]; //记录此时所在的方块数量
void init()
{
for(int i=0; i<=30001; i++)
{
f[i]=i;
deep[i]=0; //
num[i]=1; //初始时为一啦
}
}
//找祖宗,并更新距离
int getf(int v)
{
if(f[v]==v)return v;
int fa=f[v]; //
f[v]=getf(f[v]); //递归找祖宗
deep[v]+=deep[fa]; //通过递归不断地更新距离(V与父亲距离+父亲与父亲的父亲+....与·祖宗的距离)
return f[v];
}
//合并
void merge(int v,int u)
{
int t1=getf(v);
int t2=getf(u);
if(t1!=t2)
{
f[t1]=t2;
deep[t1]+=num[t2]; //合并时要加上方块数
num[t2]+=num[t1];
num[t1]+=num[t2];
}
}
int main()
{
while(~scanf("%d",&m))
{
char s[5];
init();
int a,b;
for(int i=0; i<m; i++)
{
scanf("%s",&s);
if(strcmp(s,"M")==0)
{
scanf("%d%d",&a,&b);
merge(a,b);
}
else
{
scanf("%d",&a);
getf(a); //这一步很重要,因为在此之前可能没有更新他的距离(先前没有输入过)
printf("%d\n",deep[a]);
}
}
}
return 0;
}