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
 

题解

用链表来更好的遍历每种颜色 暴力遍历算对答案的贡献
合并时用启发式合并 就是如果s[b]<s[a] 就把b和入a 但是把a和b真实对应的颜色改一下(很常用的技巧)
 
那么对于最不好的情况 也就是每次s[b]=s[a]
合并时 s扩大logn次 如果把同一个s级别的一起看 每次O(n) 所以最坏时间复杂度O(nlogn)
虽然这道题不用启发式合并速度也差不多(但就要注意b为空的情况了 启发式合并可以直接避免)
 
再次记一下合并链表步骤(合a入b)
next[b尾]=a首;b首=a首;清空a;
 

代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=1e5+,M=1e6+; int c[N],next[N],head[M],last[M],p[M],s[M];
int n,m,ans; int solve(int a,int b){
s[b]+=s[a];s[a]=; for(int i=last[a];i;i=next[i]){
if(c[i-]==b) ans--;
if(c[i+]==b) ans--;
}
for(int i=last[a];i;i=next[i]) c[i]=b; next[head[b]]=last[a];
head[b]=head[a];
last[a]=head[a]=;
} int main(){
scanf("%d%d",&n,&m); for(int i=;i<=n;i++){
scanf("%d",&c[i]);
p[c[i]]=c[i];
s[c[i]]++;
if(c[i]!=c[i-]) ans++;
if(!last[c[i]]) head[c[i]]=i;
next[i]=last[c[i]];
last[c[i]]=i;
} int x,a,b;
for(int i=;i<=m;i++){
scanf("%d",&x);
if(x==){
scanf("%d%d",&a,&b);
if(a==b) continue;
if(s[p[a]]>s[p[b]]) swap(p[a],p[b]);
a=p[a];b=p[b];
if(!s[a]) continue;
solve(a,b);
}
else printf("%d\n",ans);
} return ;
}

【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁的更多相关文章

  1. bzoj1483: [HNOI2009]梦幻布丁(vector+启发式合并)

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 4022  Solved: 1640[Submit][Statu ...

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

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

  3. BZOJ1483: [HNOI2009]梦幻布丁

    传送门 名字起得很高端实际上很简单的算法hhh 启发式合并 简单讲就是一些合并一堆队列的题可以用启发式合并,或者说这是一个思想.每次把小的合并到大的部分,均摊复杂度$O(MlogN)$. //BZOJ ...

  4. bzoj1483: [HNOI2009]梦幻布丁(链表+启发式合并)

    题目大意:一个序列,两种操作. ①把其中的一种数修改成另一种数 ②询问有多少段不同的数如1 2 2 1为3段(1 / 2 2 / 1). 昨晚的BC的C题和这题很类似,于是现学现写居然过了十分开心. ...

  5. BZOJ1483——[HNOI2009]梦幻布丁

    1.题目大意:这题就是给你一个序列,有两个操作,一个是询问序列中的连续段数,比如序列 1 2 2 1就是三段.. 1是一段,2 2 又是一段,1又是一段,就是相同的在一起,第二个操作就是将其中的一种数 ...

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

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

  7. bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1818  Solved: 761[Submit][Status ...

  8. BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )

    把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...

  9. BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]

    1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...

随机推荐

  1. Orcale 存储过程实践总结

    由于项目中用到存储过程,这两天把存储过程方面的知识简单回顾了一下并分享给大家. 编写第一个存储过程 create or replace procedure ky_proc_in_out(para3 i ...

  2. IT轮子系列(三)——如何给返回类型添加注释——Swagger的使用(二)

    前言 一般对外提供API,都会统一一个返回类型,比如所有的接口都统一返回HttpResponseMessage.这样当我们在方法上添加///注释时,是无法清楚的知道都返回字段都又那些以及它们的数据类型 ...

  3. majority element(数组中找出出现次数最多的元素)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  4. 利用LinkedHashMap实现简单的缓存

    update1:第二个实现,读操作不必要采用独占锁,缓存显然是读多于写,读的时候一开始用独占锁是考虑到要递增计数和更新时间戳要加锁,不过这两个变量都是采用原子变量,因此也不必采用独占锁,修改为读写锁. ...

  5. Scala编程入门---Map与Tuple

    创建Map //创建一个不可变的Map val ages = Map("Leo" -> 30,"Jen" ->25,"Jack" ...

  6. lintcode 在O(1)时间复杂度删除链表节点

    题目要求 给定一个单链表中的一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点. 样例 Linked list is 1->2->3->4, and giv ...

  7. jmeter接口测试报java.net.SocketException: Socket closed错误。

    如题,jmeter报出java.net.SocketException: Socket closed,我查询了下,服务器是正常的,可以返回数据,基本确定问题出在我这边jmeter.查询原因,看到有人说 ...

  8. redis两种持久化方法对比分析

    1.前言 最近在项目中使用到Redis做缓存,方便多个业务进程之间共享数据.由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能, ...

  9. Springboot+JPA+Thymeleaf 校园博客完整小网站

    本文所属[知识林]:http://www.zslin.com/web/article/detail/35 此项目是一个比较简易的校园博客.麻雀虽小五脏俱全,虽然是比较简易的但是涉及的知识点还是比较全面 ...

  10. python多线程(一)

    ---恢复内容开始--- 首先先来看个单线程的例子: from time import ctime,sleep def music(): ): print("I was listening ...