题目链接

给出 \(n\) 个布丁,每个补丁都有其颜色。现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色。

操作中可能会插入询问,回答目前总共有多少段颜色。

$1 \leq n,m \leq 10^5 $

 

考虑稍微暴力点的做法,每次暴力修改颜色,然后如果对于当前的颜色,找到他们所有的位置,假设其中一个为 \(p\) ,那么通过判断 \(p-1,p+1\)位置的颜色是否为 \(y_i\) 即可。

如果这样做,就需要链表来寻找位置。但是这样还是要超时,复杂度可能为 \(O(n^2)\)。

在这里,可以使用启发式合并,即是每次把小范围并到大范围上去,由于小范围中的数每被并一次,范围中的数至少增大一倍,也就是说每个数最后被并 \(\log(n)\) 次,总的复杂度为 \(O(nlogn)\) 的。

但目前考虑到这里还不足以解决问题,因为题目给出的 “\(x_i,y_i\)”不一定满足 \(x_i<y_i\)。

这里的解决方法就是还是将小范围并到大范围,这里中间的判断操作是不影响的,唯一有变化的就是最终的颜色,我们用一个数组来记录一下最终的颜色就可以了。\(f[i]=j\) 的含义就为 \(i\) 颜色目前为颜色为 \(j\) 的链,然后每次找 \(f[i]\) 即可。数组可以解决很多事情~

具体见代码吧:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 5;
int n, m, ans;
int col[N], first[N], nxt[N], head[N], sz[N], f[N];
int now_c[N] ;
void merge(int x, int y) {
for(int i = head[x]; i; i = nxt[i])
ans -= (col[i - 1] == y) + (col[i + 1] == y);
for(int i = head[x]; i; i = nxt[i]) col[i] = y;
nxt[first[x]] = head[y];
head[y] = head[x];
sz[y] += sz[x]; sz[x] = 0; head[x] = 0;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0) ;
cin >> n >> m;
for(int i = 1; i <= n; i++) {
cin >> col[i] ;
f[col[i]] = col[i] ;
if(col[i] != col[i - 1]) ans++ ;
if(!head[col[i]]) first[col[i]] = i;
++sz[col[i]]; nxt[i] = head[col[i]]; head[col[i]] = i ;
}
for(int i = 1; i <= m; i++) {
int op, x, y;
cin >> op;
if(op == 2) cout << ans << '\n';
else {
cin >> x >> y ;
if(sz[f[x]] > sz[f[y]]) swap(f[x], f[y]) ;
if(sz[f[x]] == 0) continue ;
merge(f[x], f[y]) ;
}
}
return 0;
}

洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. 洛谷 3201 [HNOI2009]梦幻布丁 解题报告

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

随机推荐

  1. Spring自定义标签解析与实现

           在Spring Bean注册解析(一)和Spring Bean注册解析(二)中我们讲到,Spring在解析xml文件中的标签的时候会区分当前的标签是四种基本标签(import.alias ...

  2. SpringMvc跨域支持

    SpringMvc跨域支持 在controller层加上注解@CrossOrigin可以实现跨域 该注解有两个参数 1,origins  : 允许可访问的域列表 2,maxAge:飞行前响应的缓存持续 ...

  3. java_web连接SQL_server详细步骤

    (1).我用的是Myeclipse,可以直接将sqljdbc4.jar拷到项目文件 (2).点开SQL Server配置管理器 选中SQL Server2008网络配置下的SQLEXPRESS的协议, ...

  4. Mevan(转)

    Missing artifact com.oracle:ojdbc6:jar:11.2.0.1.0问题解决 ojdbc包pom.xml出错 置顶 2017年08月23日 10:55:25 阅读数:96 ...

  5. angularJS1笔记-(20)-模块化加载机制seajs

    SeaJS是一个遵循CMD规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制. 与jQuery等JavaScript框架不同,SeaJS不会扩展封装语言特性,而 ...

  6. 『编程题全队』Alpha 阶段冲刺博客集合

    『编程题全队』Alpha 阶段冲刺博客集合 »Day1 2018年4月19日 博客连接:『编程题全队』Alpha 阶段冲刺博客Day1 »Day2 2018年4月20日 博客连接:『编程题全队』Alp ...

  7. sqlsever实现更改字段名

    新建表:create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default '默认值' null ...

  8. android自动化之appium的环境搭建

    简介appium     appium是C/S架构,appium的核心是一个web服务器,它提供了一套REST的接口,他会接收客户端的连接,监听到命令.执行会再将结果通过HTTP响应返还给客户端.ap ...

  9. poj 2299 Ultra-QuickSort(树状数组求逆序数)

    链接:http://poj.org/problem?id=2299 题意:给出n个数,求将这n个数从小到大排序,求使用快排的需要交换的次数. 分析:由快排的性质很容易发现,只需要求每个数的逆序数累加起 ...

  10. spring远程服务知识梳理

    序:本文主要是总结和归纳spring的远程服务相关知识,可作为入门学习笔记.写博客目的也是为了进行知识梳理,便于以后查看.本文主要参考资料 spring 实战第三版 本文主要讨论内容如下: 远程调度概 ...