90分求调-#7WA-梦幻布丁-启发式合并
查看原帖
90分求调-#7WA-梦幻布丁-启发式合并
188769
Vanilla_chan楼主2021/2/22 11:46

算法:

并查集维护合并的颜色,并查集合并也是启发式的。

然后就是正常的vector代替链表操作;

#define N 100010
int n,m;
int a[N];
vector<int>color[N*10];
int ans;
int f[N*10];
int getf(int x)
{
	if(x==f[x]) return x;
	return f[x]=getf(f[x]);
}
int main()
{
//	freopen("P3201_7.in","r",stdin);
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		color[a[i]].push_back(i);
	}
	for(int i=1;i<N*10;i++) f[i]=i;
	ans=1;
	for(int i=2;i<=n;i++)
	{
		if(a[i]!=a[i-1]) ans++;
	}
	int op,x,y;
	while(m--)
	{
		op=read();
		if(op==1)
		{
			x=read();
			y=read();
			x=getf(x);
			y=getf(y);
			if(x==y) continue;
			if(color[x].size()<color[y].size()) swap(x,y);
			for(int i=0;i<color[y].size();i++)
			{
				if(color[y][i]-1&&a[color[y][i]-1]==x) ans--;
				if(color[y][i]+1<=n&&a[color[y][i]+1]==x) ans--;
			}
			for(int i=0;i<color[y].size();i++) color[x].push_back(color[y][i]),a[color[y][i]]=x;
			color[y].clear();
			f[y]=x;
		}
		else write(ans);
//		for(int i=1;i<=n;i++) cout<<a[i]<<" ";
//		cout<<endl;
	}

谢谢……

2021/2/22 11:46
加载中...