习题:Cube Stacking(带权冰茶姬)

题目

传送门

思路

我们单独考虑如果将包含\(x\)的立方柱移动包含\(y\)的立方柱上会有什么影响

首先对于原来的包含\(y\)的立方柱,所有的答案都不会发生任何变化

对于包含\(x\)的立方柱,他们所有的答案都会加上包含\(y\)的立方柱的大小

简单的去考虑,这道题可以用平衡树去做

毕竟操作只有求值,平衡树的合并,区间加法

时间复杂度为\(O(nlog_n)\)

本篇博客主要介绍带权冰茶姬的做法

其实也差不多,

因为每一次的操作都是针对整个冰茶姬进行操作

所以我们所有的操作都可以直接打到根上,

\(findset\)操作的时候用父亲节点的信息进行维护

至于\(size\)的维护更简单

只有在合并两个冰茶姬的时候维护一下就可以了

代码

#include<iostream>
using namespace std;
int n;
int fa[30005];
int siz[30005];
int ans[30005];
char opt;
inline void makeset(int n)
{
	for(int i=1;i<=30000;i++)
	{
		fa[i]=i;
		siz[i]=1;
		ans[i]=0;
	}
}
inline int findset(int u)
{
	if(fa[u]==u)
		return u;
	int t=fa[u];
	fa[u]=findset(fa[u]);
	ans[u]+=ans[t];
	return fa[u];
}
inline void unionset(int a,int b)
{
	int u=findset(a);
	int v=findset(b);
	if(u==v)
		return;
	fa[v]=u;
	ans[v]+=siz[u];
	siz[u]+=siz[v];
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	makeset(n);
	for(int i=1,u,v;i<=n;i++)
	{
		cin>>opt;
		if(opt=='M')
		{
			cin>>u>>v;
			unionset(v,u);
		}
		else
		{
			cin>>u;
			findset(u);
			cout<<ans[u]<<endl;
		}
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/loney-s/p/12940029.html