【HNOI2009】梦幻布丁

#include<cstdio>
#include<iostream>
#include<cstring>
#define maxx 100005
#define maxn 1000005
using namespace std;
int n,m,cnt,ans=0;
int c[maxx],nex[maxx];
int head[maxn],s[maxn],st[maxn],ft[maxn];
//c[i]表示第i个数字的颜色
//ft[i]第i种颜色为 ft[i]
//head[i]第i种颜色的表头,nex[i]记下一个
//s[i]第i种颜色的个数
//st[i]第i种颜色的首位置
void solve(int a,int b)
{
	for(int i=head[a];i;i=nex[i])
	{
		if(c[i+1]==b)ans--;
		if(c[i-1]==b)ans--;
	}
	for(int i=head[a];i;i=nex[i])c[i]=b;
	nex[st[a]]=head[b];head[b]=head[a];s[b]+=s[a];
	head[a]=st[a]=s[a]=0;
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&c[i]);ft[c[i]]=c[i];
		if(c[i]!=c[i-1])ans++;
		if(!head[c[i]])st[c[i]]=i;
		s[c[i]]++;nex[i]=head[c[i]];head[c[i]]=i;
	}
	for(int i=1;i<=m;i++)
	{
		int x,a,b;
		scanf("%d",&x);
		if(x==2)printf("%d
",ans);
		else 
		{
			scanf("%d%d",&a,&b);
			if(a==b)continue;
			if(s[ft[a]]>s[ft[b]])swap(ft[a],ft[b]);
			a=ft[a];b=ft[b];
			if(s[a]==0)continue;
			solve(a,b);
		}
	}
	return 0;
}

  

一蓑烟雨任平生
原文地址:https://www.cnblogs.com/wyb-----520/p/10128195.html