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+5,M=1e6+5;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]=0;for(int i=last[a];i;i=next[i]){if(c[i-1]==b) ans--;if(c[i+1]==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]=0;
}int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&c[i]);p[c[i]]=c[i];s[c[i]]++;if(c[i]!=c[i-1]) 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=1;i<=m;i++){scanf("%d",&x);if(x==1){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 0;
}

View Code

转载于:https://www.cnblogs.com/xkui/p/4535512.html

【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁相关推荐

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

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 3323  Solved: 1304 [Submit][Sta ...

  2. P3201 [HNOI2009]梦幻布丁 [启发式合并][set]

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

  3. P3201 [HNOI2009] 梦幻布丁 启发式合并

    P3201 [HNOI2009] 梦幻布丁 考察:启发式合并,set 思路: 这种不可逆的改变都应该采用启发式合并,即把集合大小小的合并到大的去.那么要统计cnt,遍历小的集合中的每个元素,它前面的那 ...

  4. 【bzoj1486】【[HNOI2009]梦幻布丁】启发式链表合并(详解)

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

  5. [HNOI2009]梦幻布丁

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

  6. HYSBZ 1483 梦幻布丁

    HYSBZ 1483 梦幻布丁 模拟链表,链表启发式合并 题意 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的 ...

  7. 【进阶课】启发式合并

    启发式合并 问题概述: 有 n n n 个元素,分成 m m m 个集合.依次操作对 m m m 个集合进行两两合并. 算法思想: 每次合并都把小集合中的元素往大集合里放.对每个元素来说,所在集合个数 ...

  8. 【BZOJ1483】【codevs2335】【hdu5997】梦幻布丁+加强版,LCA+主席树

    传送门1 传送门2 传送门3 思路: 这还要从上一周的BC说起-- 因为正好放大周,在家里颓了一天后准备BC#90 干完两个签到题以后开始搞T3 抽象了很久YY出来一个并查集+主席树 连蒙带骗写了一发 ...

  9. P3201-[HNOI2009]梦幻布丁【启发式合并,链表】

    正题 题目链接:https://www.luogu.com.cn/problem/P3201 题目大意 开始有nnn个布丁,第iii个是cic_ici​颜色的. 每次有操作 将所有颜色为xxx的布丁变 ...

最新文章

  1. Ubuntu14.04安装redis和简单配置
  2. 单细胞一站式分析网站CeDR Atlas使用指南
  3. [你必须知道的.NET]第十六回:深入浅出关键字---using全接触
  4. 死锁终结者:顺序锁和轮询锁!
  5. Matlab实现CNN(二)
  6. vue框架的vue-router路由的运用
  7. 关于微软企业库中依赖注入容器Unity两种生成对象的实现
  8. 关于重定向printf出错 Error[Pe020]: identifier FILE is undefined 解决方案
  9. Android距离传感器亮屏,Android距离感应器P-Sensor浅析
  10. Shiro源码剖析——Subject的创建与获取(一次完整的请求执行流程)
  11. 还原文件打开方式为未知应用程序
  12. 解决PageHelper版本不匹配,结果可能全部返回问题
  13. Spring boot Mybatis-Plus数据库单测实战(三种方式)
  14. 初识文件管理、文件的逻辑结构
  15. 知乎:在卡内基梅隆大学 (Carnegie Mellon University) 就读是怎样一番体验?
  16. 外网使用easyconnect链接校园网
  17. PIX Moving x 宝马 | DIGITAL PLANT
  18. qt 多线程、信号槽、moveToThread等机制之拨乱反正
  19. 银行暑期实习生面试经验
  20. 什么是rest,什么是restful

热门文章

  1. [react] React中在哪捕获错误?
  2. Taro+react开发(98):问答模块05样式调整
  3. react学习(60)--ant design中getFieldDecorator
  4. react学习(41)----react中的jsx简介
  5. [html] const nums1 = [1, 2, 2, 1], nums2 = [2] 交集是什么?
  6. [css] 说说你对table-layout的理解,它有什么运用场景?
  7. [css] 你了解CSS Houdini吗?说说它的运用场景有哪些?
  8. [js] fetch和axios请求的原理都是基于XMLHttpRerequst吗?
  9. 工作55:对v-model的理解
  10. GY歌谣之读懂每行代码(飞智)