luogu P3201 [HNOI2009]梦幻布丁
先考虑暴力,显然每次是把一个位置集合和另一个集合合并,同时维护答案,合并的过程中如果两个集合每有一对元素相邻,答案就减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]梦幻布丁的更多相关文章
- 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
- P3201 [HNOI2009]梦幻布丁
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- 洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)
题面 luogu 题解 什么是启发式合并? 小的合并到大的上面 复杂度\(O(nlogn)\) 这题颜色的修改,即是两个序列的合并 考虑记录每个序列的\(size\) 小的合并到大的 存序列用链表 但 ...
- 洛谷P3201 [HNOI2009]梦幻布丁
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1818 Solved: 761[Submit][Status ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
- BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]
1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...
- [HNOI2009] 梦幻布丁
[HNOI2009] 梦幻布丁 标签: 链表 题解 可以直接用链表启发式合并做. 合并的细节处理稍微有点麻烦. 假如需要变成另一种颜色的那个颜色的个数更多,那么就肯定不能直接合. 维护一个color数 ...
随机推荐
- 第二十五篇-Android 应用资源
这里介绍android的一些资源文件. 以一个登录界面为例. layout.xml <?xml version="1.0" encoding="utf-8" ...
- Autotools知识点
最近研究了下glog使用autotools编译方法的脚本文件,略有所得 configure.ac AC_INIT初始化一些信息 Package Version ReportBug AC_CONFIG_ ...
- Ubuntu16安装wine(转)
原文:ubuntu16.04安装最新版本的wine 1.安装源 sudo add-apt-repository ppa:wine/wine-builds sudo apt-get update 2.安 ...
- 如何修改const常量值
总结:这个跟计算机语言类别和编译器有关,本文是在linux环境下说明的. 分两种情况: 1. C语言: 2. C++语言: /*! * \Description: * \author scictor ...
- Java的一些基本术语
1. 反射 获取类本身,就叫“反射”,有以下3种方式: // 通过“实例”获取类 String str = "hello"; Class cls1 = str.getClass() ...
- 2017-12-15python全栈9期第二天第五节之while else的用法二当不被break打断时else内容的结果会被打印
#!/user/bin/python# -*- coding:utf-8 -*-count = 0while count <=5 : count += 1 if count == 3 : pas ...
- flask get和post请求使用
直接看代码 #-*-coding:utf-8-*- from flask import Flask,url_for,redirect,render_template,request app = Fla ...
- 《玩转Django2.0》读书笔记-编写URL规则
<玩转Django2.0>读书笔记-编写URL规则 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. URL(Uniform Resource Locator,统一资源定位 ...
- Windows Dll Injection、Process Injection、API Hook、DLL后门/恶意程序入侵技术
catalogue 1. 引言2. 使用注册表注入DLL3. 使用Windows挂钩来注入DLL4. 使用远程线程来注入DLL5. 使用木马DLL来注入DLL6. 把DLL作为调试器来注入7. 使用c ...
- JavaFX 简介
JavaFX 介绍一提到Java的图形界面库,我们通常听到的都是Swing,或者更老一点的AWT,包括很多书上面介绍的也都是这两种.很多学校.培训班教学的也是这两种技术.但是其实这两种技术都已经过时很 ...