【BZOJ1483】【链表启发式合并】梦幻布丁
Description
N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色.
Input
第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2...An表示第i个布丁的颜色从第三行起有M行,对于每个操作,若第一个数字是1表示要对颜色进行改变,其后的两个整数X,Y表示将所有颜色为X的变为Y,X可能等于Y. 若第一个数字为2表示要进行询问当前有多少段颜色,这时你应该输出一个整数. 0
Output
针对第二类操作即询问,依次输出当前有多少段颜色.
Sample Input
1 2 2 1
2
1 2 1
2
Sample Output
1
HINT
Source
【分析】
转来的启发式合并的复杂度均摊分析:orzz
/*
纳兰性德
人生若只如初见,何事秋风悲画扇。
等闲变却故人心,却道故人心易变。
骊山语罢清宵半,泪雨霖铃终不怨。
何如薄幸锦衣郎,比翼连枝当日愿。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int MAXN = + ;
const int INF = ;
const int SIZE = ;
const int MAXM = + ;
const int maxnode = 0x7fffffff + ;
using namespace std;
struct Node{
int num;
Node *next;
}*head[MAXM];//head为表头
int cnt[MAXM], rem[MAXM], data[MAXM];
int tot, n, m; //在链表中加入颜色为x的节点
void add(int x, int d){//d代表位置
if (cnt[x] == ){
head[x] = new Node;
head[x]->num = d;
head[x]->next = NULL;
}else{
//在表头插入
Node *p = new Node;
p->num = d;
p->next = head[x];
head[x] = p;
}
}
void init(){
tot = ;//记录颜色的总数
memset(cnt, , sizeof(cnt));//记录颜色的数量
scanf("%d%d", &n, &m);
//for (int i = 1; i <= n; i++) rem[i] = i;
data[] = -INF;
for (int i = ; i <= n; i++){
scanf("%d", &data[i]);//输入颜色
if (data[i] != data[i - ]) tot++;
cnt[data[i]]++;
add(data[i], i);
rem[data[i]] = data[i];//防错数组初始化
} }
//将a颜色变成b颜色
void change(int a, int b){
//不要搞错了是比较正确颜色的个数
if (cnt[rem[a]] > cnt[rem[b]]) swap(rem[a], rem[b]);
a = rem[a];//总是让颜色数量少的变成多的
b = rem[b];
if (cnt[a] == ) return;
cnt[b] += cnt[a];
cnt[a] = ;
Node *cur;
for (cur = head[a]; cur != NULL; cur = cur->next){
if (data[cur->num + ] == b) tot--;
if (data[cur->num - ] == b) tot--;
}
for (cur = head[a]; cur->next != NULL; cur = cur->next) data[cur->num] = b;
data[cur->num] = b;
//最后将a插在b后面
cur->next = head[b];
head[b] = head[a];
}
void work(){
for (int i = ; i <= m; i++){
int t, a, b;
scanf("%d", &t);
if (t == ) printf("%d\n", tot);
else{
scanf("%d%d", &a, &b);
if (a == b) continue;//两种颜色相同
change(a, b);
}
}
//for (int i = 1; i <= n; i++) printf("%d", data[i]);
} int main(){ init();
work();
return ;
}
【BZOJ1483】【链表启发式合并】梦幻布丁的更多相关文章
- bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1818 Solved: 761[Submit][Status ...
- 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并
[BZOJ1483][HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2 ...
- 【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- BZOJ1483 [HNOI2009]梦幻布丁 【链表 + 启发式合并】
题目 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入格式 第一行给出N,M表示 ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
- BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]
1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...
- bzoj 1483: [HNOI2009]梦幻布丁 (链表启发式合并)
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- BZOJ 1483:[HNOI2009]梦幻布丁(链表+启发式合并)
[HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一 ...
随机推荐
- autoit使用
autoit下载地址: http://www.autoitx.com/thread-12964-1-1.html?sid=4zMMSb 在autoit的安装目录下有个Au3Info.exe文件,该文件 ...
- POJ 1775 (ZOJ 2358) Sum of Factorials
Description John von Neumann, b. Dec. 28, 1903, d. Feb. 8, 1957, was a Hungarian-American mathematic ...
- ubuntu 桌面
u盘虚拟光驱打开.ios,读写到u盘 goagent:wine goagent.exe的路径:右键在终端中运行proxy.py. 终端中wine exe文件 ubuntu安装镜像文件: 下载压缩包解压 ...
- 整数区间及区间集合(C#实现)
/// <summary> /// 整数区间类 /// </summary> private class Interval { , _end = ; public int St ...
- Google表单
本博文的主要内容有 .Google表单的介绍 https://www.google.com/intl/zh-CN/forms/about/ 自行去注册Google账号,不多,赘述.
- Java中json工具对比分析
Java中几个json工具分析 1, 环境 JDK1.6+IDE(IntelliJ IDEA)+windowsXP+GBK编码 2,分析对象 jackson1.8.2 http://jackson.c ...
- mysql定时器三部曲
1.查看事件状态 SELECT @@event_scheduler; 或 show VARIABLES LIKE '%sche%'; 2.创建存储过程 示例一批量新增: delimiter | ...
- SQL profile纵览(10g)
第一篇:介绍 10g开始,查询优化器(Query optimizer)扩展成自动调整优化器(Automatic Tuning Optimizer).也就是扩展了功能.此时,我们就可以让 ...
- IOS 多个ImageView图片层叠透明区域点击事件穿透
经常用到多个透明图片层叠,但又需要获取不同图片的点击事件,本文实现图片透明区域穿透点击事件 实现人体各个部位点击 - (BOOL) pointInside:(CGPoint)point withEve ...
- 解决apache服务器本地可以访问,同局域网内他人不能访问的问题(转)
问题提出:发现这个问题时,我同学让我做好的网页小案例给他看看,我是用wamp搭建的本地服务器,本地访问地址例如为: http://localhost/Dedecms/index.php 对于其他人要访 ...