【HNOI2009】梦幻布丁
题目描述
N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色。
输入输出格式
输入格式
第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2...An表示第i个布丁的颜色从第三行起有M行,对于每个操作,若第一个数字是1表示要对颜色进行改变,其后的两个整数X,Y表示将所有颜色为X的变为Y,X可能等于Y. 若第一个数字为2表示要进行询问当前有多少段颜色,这时你应该输出一个整数. 0
输出格式
针对第二类操作即询问,依次输出当前有多少段颜色.
数据范围
\(1\le n,m\le100,000\); \(0<A_i,x,y<1,000,000\)
题解
起初用的线段树维护,可是如果被卡的话,时间复杂度就变成了\(O(n^2log_2n)\)了,所以,看了Hzwer大佬的博客后知道要用链表来解决,我们可以发现,对于一种颜色的操作,是把所有相同颜色都进行改变,所以我们把每种颜色都开一条链来维护,对于每次操作都是将两条链合并,一般的合并时间复杂度是\(O(n)\)的,所以我们要考虑启发式合并,每次我们都会使该条链的长度变为原长度的两倍以上,所以,我们最多只会合并\(log_2n\)次,但是,这样我们就会发现,我们每次合并后颜色可能会发生错位,我们需要利用一个数组来记录这种错位。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005, MAXM = 1000005;
int color[MAXN], ft[MAXM], Head[MAXM], Next[MAXN], Stern[MAXM], Size[MAXM];
int ans = 0;
void Merge(int x, int y)
{
for(int i = Head[x]; i != -1; i = Next[i])
{
if(color[i + 1] == y) ans --;
if(color[i - 1] == y) ans --;
}
for(int i = Head[x]; i != -1; i = Next[i]) color[i] = y;
Next[Stern[x]] = Head[y], Size[y] += Size[x], Head[y] = Head[x];
Head[x] = -1 ,Stern[x] = Size[x] = 0;
return;
}
int main()
{
int opt, x, y;
memset(Head, -1, sizeof(Head));
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; ++ i)
{
scanf("%d", &color[i]);
ft[color[i]] = color[i];
if(color[i] != color[i - 1]) ans ++;
if(Head[color[i]] == -1) Stern[color[i]] = i;
Next[i] = Head[color[i]], Head[color[i]] = i, Size[color[i]] ++;
}
for(int i = 1; i <= m; ++ i)
{
scanf("%d", &opt);
if(opt == 2) printf("%d\n", ans);
else{
scanf("%d%d", &x, &y);
if(x == y) continue;
if(Size[ft[x]] > Size[ft[y]]) swap(ft[x], ft[y]);
x = ft[x], y = ft[y];
if(Size[x] == 0) continue;
Merge(x, y);
}
}
return 0;
}
【HNOI2009】梦幻布丁的更多相关文章
- 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数 ...
- bzoj 1483: [HNOI2009]梦幻布丁 启发式合并vector
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description N个 ...
- 1483: [HNOI2009]梦幻布丁
1483: [HNOI2009]梦幻布丁 链接 分析: 启发式合并+链表. 代码: #include<cstdio> #include<algorithm> #include& ...
- 洛谷 3201 [HNOI2009]梦幻布丁 解题报告
3201 [HNOI2009]梦幻布丁 题目描述 \(N\)个布丁摆成一行,进行\(M\)次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为\(1,2,2 ...
- bzoj 1483: [HNOI2009]梦幻布丁
1483: [HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1 ...
- BZOJ 1483:[HNOI2009]梦幻布丁(链表+启发式合并)
[HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一 ...
- 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并
[BZOJ1483][HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2 ...
随机推荐
- tomcat的8088端口被占用
打开Dos:windows->输入cmd(想必这个都会) 在黑窗口中输入指令:netstat -ano | findstr 8080 指令的意思是找出占用8080端口的进程pid 再 ...
- 最近在研究asp.net mvc
看了很多大牛写的博客,依然对mvc云里雾里. 有一点是毋庸置疑的C应该是一座桥梁建立在model和view之间. 在ASP.NET MVC中,控制器通常是继承System.Web.Mvc.Contro ...
- MySQL---1、介绍
一.MySQL简介 1.MySQL简介 MySQL是一个轻量级关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司.目前MySQL被广泛地应用在Internet上的中小型网站 ...
- Vue 2.0的学习笔记:Vue的过滤器
转自: https://www.w3cplus.com/vue/how-to-create-filters-in-vuejs.html 过滤器的介绍 1.在Vue中使用过滤器(Filters)来渲染数 ...
- ASP.NET 简单的柱形图实现(附带示例)
对于一些内部系统的项目,各种图表是在所难免的,因为图表可以更加清晰的表达出想看到的数据. 因为之前从来没有做过关于图表的东西,唯一能想到的就是“验证码”,所以应该是一个思路,用GDI去搞. 数据懒着去 ...
- 常见IT英语单词
lable标签,master精通.主人,reference参考,release发布,schema模式,component组件,persistence持久化,generate生成产生,plugin插件, ...
- nginx 安装配置和常用命令
基本环境:CentOS 1. 下载 nginx [root@localhost ~]# cd Downloads/ [root@localhost Downloads]# wget http://ng ...
- CentOS-Linux系统下安装JDK
一般情况下,Linux系统都有自带的JDK,但不符合开发要求,所以需要卸载,重新安装JDK 步骤1:查看现有安装的JDK版本 命令: rpm -qa | grep -i java 步骤2:卸载已有软件 ...
- JDBC入门(1)—— 入门案例
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组 ...
- 手写堆优化dijkstra
\(dijkstra\) 算法的堆优化,时间复杂度为\(O(n+m)\log n\) 添加数组\(id[]\)记录某节点在堆中的位置,可以避免重复入堆从而减小常数 而这一方法需要依托手写堆 #incl ...