堆积方块

方块游戏

cubes.pas/c/cpp)

【题目描述】

    A和小B在玩一个方块游戏。编号为1到n(1<=n<=30000)的n个方块正放在地上。每个构成一个立方柱。

    游戏开始后,小A会给小B发出p(1<=p<=100000)个指令。

    1、移动(M):将包含X的立方柱移动到包含Y的立方柱上。

    2、统计(C):统计含X的立方柱中,在X下方的方块数目。

    写个程序帮小B完成游戏。

【输入数据】

    1行输入P,之后P行每行输入一条指令。形式为“M X Y”或者“C X”。

    输入保证不会有将立方柱放在自己头上的指令。

【输出数据】

    每一行,对于每个统计指令,输出其结果。

【样例输入】

6

M 1 6

C 1

M 2 4

M 2 6

C 3

C 4

【样例输出】

1

0

2

【数据范围】

对于40%的数据,n,P≤200。

对于60%的数据,n,P≤2000。

对于100%的数据,n,P≤100000。




分析:

非常巧妙地并查集。

题目说的是将A放在B上,显然我们维护并查集时用路径压缩,那么要计算下方的个数,显然是做不到的,所以我们更换思路:

将B放在A上面,那么题意所指的A下方的方块其实就是我们更改题意后的A上方的方块数,路径压缩和合并的时维护一下就可以了。


参考程序:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=110000;
int f[maxn],ans[maxn],sum[maxn];
int find(int x){
	if (f[x]==x)return x;
	if (f[f[x]]==f[x])return f[x];
	find(f[x]);ans[x]+=ans[f[x]];f[x]=f[f[x]];
	return f[x];
}
void move(int u,int v){
	int fu=find(u),fv=find(v);
	ans[fu]+=sum[fv];f[fu]=fv;sum[fv]+=sum[fu];
}
int main(){
	freopen("cubes.in","r",stdin);
	freopen("cubes.out","w",stdout);
	int T;
	scanf("%d",&T);
	for (int i=1;i<=T;i++)
		f[i]=i,sum[i]=1,ans[i]=0;
	while (T--){
		char cmd;
		scanf("\n%c",&cmd);
		if (cmd=='M'){
			int x,y;
			scanf("%d%d",&x,&y);
			move(x,y);
		}else{
			int x;
			scanf("%d",&x);
			find(x);
			printf("%d\n",ans[x]);
		}
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值