ʕ·͡ˑ·ཻ ʕ•̫͡• ʔ•̫͡•ཻʕ•̫͡•ʔ•͓͡•ʔ

题目 - Cube Stacking

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

* 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

Print the output from each of the count operations in the same order as the input file.

Sample Input

1
2
3
4
5
6
7
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

Sample Output

1
2
3
1
0
2

题意:

有若干个方块,经p次操作后,在x方块下面的方块有多少个,M操作—>将包含x方块的堆移到含y的堆上,C操作—>输出x方块下方方块的数目。

思路:

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
using namespace std;
int f[30010],cnt[30010],up[30010];
int find(int x)
{
int y;
if(x!=f[x])
{
y=f[x];
f[x]=find(y);
up[x]+=up[y];
}
return f[x];
}
void Union(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py)
return ;
front[py]=px;
up[py]=cnt[px];
cnt[px]+=cnt[py];
}
int main()
{
int p,i,j,x,y;
char a;
cin>>p;
for(i=1;i<=30000;i++)
{
f[i]=i;
cnt[i]=1;
up[i]=0;
}
while(p--)
{
cin>>a;
if(a=='M')
{
scanf("%d%d",&x,&y);
Union(x,y);
}
else
{
scanf("%d",&x);
int px=find(x);
printf("%d\n",cnt[px]-up[x]-1);
}
}
return 0;
}
  • 还有一种思路是把父亲放在下面,过程与上图类似,只不过是倒过来了。

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<iostream>
using namespace std;
int f[30010],cnt[30010],dis[30010];
int find(int x)
{
int y;
if(x!=f[x])
{
y=f[x];
f[x]=find(f[x]);
dis[x]+=dis[y];
}
return f[x];
}
void Union(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py)
return ;
f[px]=py;
dis[px]+=cnt[py];
cnt[py]+=cnt[px];
}
int main()
{
int p,i,j,x,y;
char a;
cin>>p;
for(i=1;i<=30000;i++)
{
front[i]=i;
dis[i]=0;
cnt[i]=1;
}
while(p--)
{
cin>>a;
if(a=='M')
{
scanf("%d%d",&x,&y);
Union(x,y);
}
else
{
scanf("%d",&x);
find(x);
cout<<dis[x]<<endl;
}
}
return 0;
}