传送门

先考虑暴力,显然每次是把一个位置集合和另一个集合合并,同时维护答案,合并的过程中如果两个集合每有一对元素相邻,答案就减1

优化暴力的话,说到合并,怎么能不想起启发式合并呢?每次把一个大小小的集合并到大的上面,如果一个元素合并一次是\(O(1)\),总复杂度就是\(O(nlogn)\).实现的化可以使用平衡树/set,也可以大力链表

注意可能本来是\(x\)变成\(y\)颜色的,但是因为启发式合并,交换\(x,y\)以后变成\(y\)变\(x\),这样会出问题,这个时候要用\(f_x\)表示\(x\)指代的颜色,然后交换只要交换\(f\)救星了

更多细节详见代码

#include<bits/stdc++.h>
#define LL long long
#define db double
#define il inline
#define re register using namespace std;
const int N=1e6+10;
il int rd()
{
int x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int n,m,c[N],ans,f[N],sz[N],nt[N],hd[N],tl[N]; int main()
{
n=rd(),m=rd();
for(int i=1;i<=n;++i)
{
c[i]=rd(),ans+=c[i]!=c[i-1];
f[c[i]]=c[i];
if(!tl[c[i]]) hd[c[i]]=i;
else nt[tl[c[i]]]=i;
++sz[c[i]],tl[c[i]]=i;
}
while(m--)
{
int op=rd();
if(op==1)
{
int &x=f[rd()],&y=f[rd()];
if(x==y) continue;
if(sz[x]>sz[y]) swap(x,y);
if(!sz[x]) continue;
for(int i=hd[x];i;i=nt[i]) ans-=(c[i-1]==y)+(c[i+1]==y);
for(int i=hd[x];i;i=nt[i]) c[i]=y;
nt[tl[x]]=hd[y],hd[y]=hd[x],sz[y]+=sz[x],x=sz[x]=hd[x]=tl[x]=0;
}
else printf("%d\n",ans);
}
return 0;
}

luogu P3201 [HNOI2009]梦幻布丁的更多相关文章

  1. 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]

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

  2. P3201 [HNOI2009]梦幻布丁

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

  3. 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)

    题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...

  4. 洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)

    题面 luogu 题解 什么是启发式合并? 小的合并到大的上面 复杂度\(O(nlogn)\) 这题颜色的修改,即是两个序列的合并 考虑记录每个序列的\(size\) 小的合并到大的 存序列用链表 但 ...

  5. 洛谷P3201 [HNOI2009]梦幻布丁

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

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

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

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

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

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

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

  9. [HNOI2009] 梦幻布丁

    [HNOI2009] 梦幻布丁 标签: 链表 题解 可以直接用链表启发式合并做. 合并的细节处理稍微有点麻烦. 假如需要变成另一种颜色的那个颜色的个数更多,那么就肯定不能直接合. 维护一个color数 ...

随机推荐

  1. ftp 两台服务器传输文件 apache

    import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputS ...

  2. Java 判断相等

    1.基本数据类型用 == long a = (long) 1234567890; long b = (long) 1234567890; if (a == b) { System.out.printl ...

  3. Vim保存时权限不足

    保存时权限不足,由于打开时忘记在命令前添加sudo.我们并不需要放弃修改,从新以root权限打开 解决方案 命令模式使用:w !sudo tee %提权,保存

  4. Windows下VMware14黑屏

    解决方法 以管理员身份运行命令提示符,执行netsh winsock reset

  5. 【UOJ 351】新年的叶子

    http://uoj.ac/problem/351 其实原来看到这题是真的不想做的 毕竟真的特别怕期望题 后来莫名发现自己打了正解 也是很震惊的2333 Description   对于一棵树,每次随 ...

  6. key-event

    效果如下 代码如下: 首先看目录 //index.html <!DOCTYPE html> <html lang="zh-CN"> <head> ...

  7. Linux下学习摄像头使用

    刚接触Linux硬件驱动有关的项目,配置摄像头经历的一些操作 (这篇文章是刚接触Linux下V4L时作为记录记下的,感觉只有几个命令还有参考作用) 一 确定摄像头种类 确定是否符合UVC标准协议,一般 ...

  8. mysql安装和操作

    1.install: 下载地址:https://dev.mysql.com/downloads/ 2.下载zip包解压: 3.自己在该文件夹下创建 my.ini,并编辑内容: [mysql] # 设置 ...

  9. Luogu P2617 Dynamic Rankings

    带修主席树的模板,因为状态不好所以敲了很长时间,不过写完感觉能更好地理解主席树了. 核心其实就是树状数组套主席树,维护方法不再是以前的那种一步一修改,而是对于树状数组上的每一个点建立一棵权值线段树,然 ...

  10. day-02(css,js)

    本文档并非个人所写,只是便于参考:回顾: html: 作用:展示 文件标签: <html> <head> <title></title> </he ...