zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    Eclipse 导入项目乱码问题(中文乱码)
    sql中视图视图的作用
    Java基础-super关键字与this关键字
    Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
    Android View和ViewGroup
    工厂方法模式(java 设计模式)
    设计模式(java) 单例模式 单例类
    eclipse乱码解决方法
    No resource found that matches the given name 'Theme.AppCompat.Light 的完美解决方案
    【转】使用 Eclipse 调试 Java 程序的 10 个技巧
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7258917.html
Copyright © 2011-2022 走看看