【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 ...
随机推荐
- JS日期、月份的加减
JS日期.月份的加减 需要注意的是返回的月份是从0开始计算的,也就是说返回的月份要比实际月份少一个月,因此要相应的加上1 // 日期,在原有日期基础上,增加days天数,默认增加1天 function ...
- MVC知识点
一· MVC MVC设计模式->MVC框架(前端开发框架),asp.net(webform) aspx M:Model (模型,负责业务逻辑处理,比如说去db中获取数据) V:View (视图 ...
- ajax success和error接收了哪些状态码
ajax和 Http Status 之前一直奇怪ajax发送请求后success 和 error 分界的状态码是多少, 主要很多将ajax的教程也没有提到, 例如, 我用ResponseEntity& ...
- java多线程(一)-五种线程创建方式
简单使用示例 Java 提供了三种创建线程的方法: 通过实现 Runnable 接口: 通过继承 Thread 类本身: 通过 Callable 和 Future 创建线程. 还有 定时器 线程池 下 ...
- 最小生成树(prim)
里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)),且 ...
- C#画个控件,指定字符特殊颜色显示
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 【Codeforces】Helvetic Coding Contest 2017 online mirror比赛记
第一次打ACM赛制的团队赛,感觉还行: 好吧主要是切水题: 开场先挑着做五道EASY,他们分给我D题,woc什么玩意,还泊松分布,我连题都读不懂好吗! 果断弃掉了,换了M和J,然后切掉了,看N题: l ...
- Install guide for OpenLDAP and GOsa 2 on Ubuntu & Debian
First we will install OpenLDAP by running the command as root: apt-get install slapd ldap-utils ldap ...
- 一步一步pwn路由器之路由器环境修复&&rop技术分析
前言 本文由 本人 首发于 先知安全技术社区: https://xianzhi.aliyun.com/forum/user/5274 拿到路由器的固件后,第一时间肯定是去运行目标程序,一般是web服务 ...
- 简析 Tomcat 、Nginx 与 Apache 的区别
简析 Tomcat .Nginx 与 Apache 的区别 本文讲的是简析 Tomcat .Nginx 与Apache的区别, 经常在用 apache 和 tomcat 等这些服务器,可是总感觉还是不 ...