[HNOI2009]梦幻布丁(链表+启发式合并)
开始一个O(n^2)思路,每次每句要改变颜色的点,改变完颜色后重新计算颜色的段数,显然拉闸。
然后呢。。然后就不会了。
看了别人博客,才知道有个叫做启发式合并的东西,就是把小的合并到大的上面,时间复杂度就将为了log级别,额,为啥呢?
反正这样就更快了。
然后对于此题
我们先求出原序列的答案
每一种颜色搞一条链把该色结点串起来,记录下链条尾结点
把一种颜色的染成另一种,很简单把它合并过去,然后处理下对于答案的影响
但是。。。
比如把1染成2,但是s[1]>s[2],这时我们应该将2合并到1的链后面,但是会遇到一个麻烦的问题,就是这个链头是接1下的,也就是说以后找颜色2,发现没有颜色2只有颜色1。。。
于是我们应该开一个数组f,表示我们寻找一种颜色时,实际应该找哪个颜色下的链,遇到上面那种情况要交换f[1]和f[2]
#include <iostream>
#include <cstdio>
#define maxn 100005 using namespace std; int n, m, maxx, ans;
int a[maxn], next[maxn], head[maxn * ], tail[maxn * ], cnt[maxn * ], f[maxn * ]; int main()
{
int i, j, x, y, opt;
scanf("%d %d", &n, &m);
for(i = ; i <= n; i++)
{
scanf("%d", &a[i]);
f[a[i]] = a[i];
if(a[i] != a[i - ]) ans++;
if(!tail[a[i]]) head[a[i]] = i;
next[i] = tail[a[i]];
tail[a[i]] = i;
cnt[a[i]]++;
}
for(i = ; i <= m; i++)
{
scanf("%d", &opt);
if(opt == )
{
scanf("%d %d", &x, &y);
if(f[x] == f[y]) continue;
if(cnt[f[x]] > cnt[f[y]]) swap(f[x], f[y]);//表头互换
x = f[x], y = f[y];
if(!cnt[x]) continue;
for(j = tail[x]; j; j = next[j])
{
if(a[j - ] == y) ans--;
if(a[j + ] == y) ans--;
}
for(j = tail[x]; j; j = next[j]) a[j] = y;
next[head[x]] = tail[y];//把 x 合并到 y 上
tail[y] = tail[x];
cnt[y] += cnt[x];
head[x] = tail[x] = cnt[x] = ;
}
else printf("%d\n", ans);
}
return ;
}
把 x 插到 y 的后面,所以得写成
next[head[x]] = tail[y];
tail[y] = tail[x];
也可以把 x 插到 y 的前面,写成
next[head[y]] = tail[x];
head[y] = head[x]
[HNOI2009]梦幻布丁(链表+启发式合并)的更多相关文章
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
		
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
 - 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并
		
[BZOJ1483][HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2 ...
 - 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\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
 - bzoj1483: [HNOI2009]梦幻布丁(链表+启发式合并)
		
题目大意:一个序列,两种操作. ①把其中的一种数修改成另一种数 ②询问有多少段不同的数如1 2 2 1为3段(1 / 2 2 / 1). 昨晚的BC的C题和这题很类似,于是现学现写居然过了十分开心. ...
 - bzoj1483: [HNOI2009]梦幻布丁(vector+启发式合并)
		
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 4022 Solved: 1640[Submit][Statu ...
 - BZOJ 1483 梦幻布丁(链表+启发式合并)
		
给出一个长度为n的序列.支持两种操作: 1.把全部值为x的修改成y.2.询问序列有多少连续段. 我们可以对于每个值建立一个链表.对于操作1,则可以将两个链表合并. 对于操作2,只需要在每次合并链表的时 ...
 - [BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并)
		
[BZOJ 1483] [HNOI2009] 梦幻布丁 (线段树合并) 题面 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1 ...
 - 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
		
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
 
随机推荐
- hashTable 和 hashMap的区别
			
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,HashMap把Hashtable的contains方法去掉了,改成containsvalue和contai ...
 - window上安装MySQL
			
一.安装MySQL 1.1 下载解压缩版的安装包,解压,然后配置环境变量 PATH=.......;D:\Program Files (x86)\mysql-5.5.27-win32\bin (注意是 ...
 - 使用JS移除select的某些选项
			
var arrvalue = new Array("1", "3", "4", "5", "6", ...
 - UVa OJ 494
			
Kindergarten Counting Game Everybody sit down in a circle. Ok. Listen to me carefully. ``Woooooo, ...
 - 07/29/2013 02:10:02 AM - CMDPHP: Poller[0] Host[6] DS[10] WARNING: Result from SNMP not valid. Partial Result: U
			
snmpwalk -c public -v2c 客户端ip地址 自定义的oid 能取到数据,但是服务器端就是图片一片空白 rrdtool fetch 文件名.rrd 查看到的全都是nan cac ...
 - How `delete’ works ?
			
这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=21 February 16, 2013 How `delete’ works ...
 - react基础语法(四) state学习
			
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
 - learnpythonthehardway EX41 相关
			
str.count() # str.count()方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. # str.count(sub, start= 0,end=len( ...
 - 导入Excel表格(二)
			
1. 提取session中的数据.并进行分页操作,上传excel表格,保存到临时表格. 初始化临时表格,提交表单,判断状态是否为真,若为真,则启用 导入到数据库 的按钮:为false,让查询的url ...
 - window.onload和DOMContentLoaded的区别
			
一.何时触发这两个事件? 1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完 ...