• 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并


    【BZOJ1483】[HNOI2009]梦幻布丁

    Description

    N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色.

    Input

    第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2...An表示第i个布丁的颜色从第三行起有M行,对于每个操作,若第一个数字是1表示要对颜色进行改变,其后的两个整数X,Y表示将所有颜色为X的变为Y,X可能等于Y. 若第一个数字为2表示要进行询问当前有多少段颜色,这时你应该输出一个整数. 0

    Output

    针对第二类操作即询问,依次输出当前有多少段颜色.

    Sample Input

    4 3
    1 2 2 1
    2
    1 2 1
    2

    Sample Output

    3
    1

    题解:我们对于每个颜色,用一个链表(或vector,或queue,或~)来维护它所有出现的位置,然后合并两个颜色时就相当于将两个链表合并,顺便记录一下有多少相邻的位置,更新一下答案即可。合并时用启发式合并即可做到nlogn。

    数据范围:好像n<=1e5,颜色<=1e6,m<=1e6

    特判:没有颜色为Y的情况,没有颜色为X的情况,X=Y的情况。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int maxn=100010;
    const int maxm=1000010;
    int n,m,tot,cnt,ans;
    int c[maxn],head[maxn],next[maxn],to[maxn];
    int bel[maxm],siz[maxn],p[maxn];
    int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    void add(int a,int b)
    {
    	next[b]=head[a],head[a]=b;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a,b,aa,bb;
    	for(i=1;i<=n;i++)
    	{
    		a=rd();
    		if(!bel[a])	bel[a]=++tot;
    		c[i]=bel[a],siz[bel[a]]++,add(bel[a],i);
    		if(c[i]!=c[i-1])	ans++;
    	}
    	for(i=1;i<=m;i++)
    	{
    		if(rd()==2)	printf("%d
    ",ans);
    		else
    		{
    			a=rd(),b=rd();
    			if(a==b)	continue;
    			if(!bel[a])	continue;
    			if(!bel[b])
    			{
    				bel[b]=bel[a],bel[a]=0;
    				continue;
    			}
    			aa=a,bb=b,a=bel[a],b=bel[b],bel[aa]=0;
    			if(siz[a]>siz[b])	swap(a,b);
    			bel[bb]=b;
    			for(p[0]=0,j=head[a];j;j=next[j])	p[++p[0]]=j,ans-=(c[j-1]==b)+(c[j+1]==b);
    			for(j=1;j<=p[0];j++)	add(b,p[j]),c[p[j]]=b;
    			head[a]=0;
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    WPF 修改Webbrowser的IE版本小程序(32位)
    AnyCAD OpenSource 版本下载和编译
    请求ajax失败的原因(进入到error)
    如何将多个数据的- 转为:来匹配josn格式
    jQuery ajax如何传多个值到后台页面,举例:
    java finalize方法总结、GC执行finalize的过程
    SQL Server索引碎片整理实际操作记录
    MYSQL手册
    Eclipse显示行号
    MyEclipse设置Console输出到文件
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7258917.html
Copyright © 2020-2023  润新知