传送门

先考虑暴力,显然每次是把一个位置集合和另一个集合合并,同时维护答案,合并的过程中如果两个集合每有一对元素相邻,答案就减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. Git错误汇总

    Git提示rejected To github.com:zhuxiaoxi/Web-Demo.git ! [rejected] master -> master (fetch first) er ...

  2. SSH出现Connection refused错误

    笔者在使用ssh localhost时出现Connection refused提示,初步判断是22端口未开启服务,也有可能是防火墙未正确配置. 测试 使用netstat | grep 22测试,发现2 ...

  3. 线性筛prime/phi/miu/求逆元模板

    这绿题贼水...... 原理我不讲了,随便拿张草稿纸推一下就明白了. #include <cstdio> using namespace std; ; int su[N],ans,top; ...

  4. navicat premium 12破解流程

    具体步骤:这是破解的具体链接 仅此记录,以供后续之需

  5. 第十六节,使用函数封装库tf.contrib.layers

    这一节,介绍TensorFlow中的一个封装好的高级库,里面有前面讲过的很多函数的高级封装,使用这个高级库来开发程序将会提高效率. 我们改写第十三节的程序,卷积函数我们使用tf.contrib.lay ...

  6. JDBC批处理(Batch)MySQL中的表

    在数据库test里先创建表school,内容如下 向school表中一次增加多行.addBatch,executeBatch import java.sql.Connection; import ja ...

  7. 我的winows server 2012 突然多了个piress的帐户,后来一查原来是mysql漏洞的问题,郁闷

    今天打开远程连接到windows server 2012,服务器上装的360竟然提示有木马.吓了一跳.再检查计算机账户,多了个piress账户.把这个账户在百度一搜索,原来还有其它人中招. 后来发现网 ...

  8. plsql界面/command界面

    存储过程执行CALL PRO_DELETE_OND_FOR_ORDERNO('120000000208');    --在PLSQL的SQL窗口执行 EXEC PRO_DELETE_OND_FOR_O ...

  9. 【好用的Mac分屏软件】Magnet for Mac 2.3

      「Magnet」是一款Mac窗口管理工具. 当您每次将内容从一个应用移动到另一应用时,当您需要并排比较数据时,或是以其他方式进行多任务处理时,你需要妥善放置所有窗口.Magnet 让这一过程清爽又 ...

  10. 一名全栈设计师的Mac工具箱(设计,开发,效率)

        我喜欢把自己定义为一个会一些设计的全栈工程师.在一些大型企业项目中,我一般担任架构师的角色,而到了我自己负责的个人或开源项目中,我就成了一名全栈设计师.我喜欢用自学而来的那些设计技能进行网站或 ...