[HNOI 2009]梦幻布丁
Description
维护一个序列 \(A\) 。支持以下操作:
- \(X~Y\) 将序列中所有的 \(X\) 变成 \(Y\) ;
- 询问序列颜色段数。
\(1\leq n,m\leq 100000,0<A_i,X,Y\leq 1000000\)
Solution
这题做法挺多的,我写的是线段树大力合并。
均摊复杂度为 \(O(n\log_2^2 n)\)
Code
//It is made by Awson on 2018.3.12
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 100000, C = 1000000;
void read(int &x) {
char ch; bool flag = 0;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }
int n, m, flag[C+5], x, ans, opt, a, b;
struct Segment_tree {
int root[C+5], ch[N*20+5][2], kl[N*20+5], kr[N*20+5], cnt[N*20+5], key[N*20+5], pos;
queue<int>mem;
void recycle(int o) {ch[o][0] = ch[o][1] = kl[o] = kr[o] = cnt[o] = key[o] = 0; mem.push(o); }
void pushup(int o) {
kl[o] = kl[ch[o][0]], kr[o] = kr[ch[o][1]], cnt[o] = cnt[ch[o][0]]+cnt[ch[o][1]];
key[o] = key[ch[o][0]]+key[ch[o][1]]-(kr[ch[o][0]] == 1 && kl[ch[o][1]] == 1);
}
void insert(int &o, int l, int r, int loc) {
if (!o) {if (!mem.empty()) o = mem.front(), mem.pop(); else o = ++pos; }
if (l == r) {kl[o] = kr[o] = cnt[o] = key[o] = 1; return; }
int mid = (l+r)>>1;
if (loc <= mid) insert(ch[o][0], l, mid, loc);
else insert(ch[o][1], mid+1, r, loc);
pushup(o);
}
int merge(int a, int b) {
if (!a || !b) return a+b;
if (cnt[a] < cnt[b]) Swap(a, b);
ch[a][0] = merge(ch[a][0], ch[b][0]);
ch[a][1] = merge(ch[a][1], ch[b][1]);
pushup(a); recycle(b); return a;
}
}T;
void work() {
read(n), read(m);
for (int i = 1; i <= n; i++) {
read(x), ans -= T.key[T.root[x]]; flag[x] = 1;
T.insert(T.root[x], 1, n, i); ans += T.key[T.root[x]];
}
while (m--) {
read(opt);
if (opt == 2) writeln(ans);
else {
read(a), read(b); if (a == b) continue;
ans -= T.key[T.root[a]]+T.key[T.root[b]], flag[a] = 0, flag[b] = 1;
ans += T.key[T.root[b] = T.merge(T.root[a], T.root[b])]; T.root[a] = 0;
}
}
}
int main() {
work(); return 0;
}
[HNOI 2009]梦幻布丁的更多相关文章
- 1483:[HNOI]2009 梦幻布丁 - BZOJ
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- 数据结构(启发式合并):HNOI 2009 梦幻布丁
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...
- [BZOJ 1483][HNOI 2009]梦幻补丁(有序表启发式合并)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1483 分析: 先将不同的颜色的出现位置从小到大用几条链表串起来,然后统计一下答案 对于 ...
- 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数 ...
- 【BZOJ1483】【HNOI2009】梦幻布丁(启发式合并,平衡树)
[BZOJ1483][HNOI2009]梦幻布丁 题面 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1 ...
- bzoj 1483: [HNOI2009]梦幻布丁 启发式合并vector
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description N个 ...
随机推荐
- springmvc与freemarker的整合
官方简介:FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具. 它不是面向最终用户的,而是一个Java ...
- Struts2学习笔记四 OGNL
OGNL,全称为Object-Graph Navigation Language(对象图表达语言),它是一个功能强大的表达式语言,用来获取和设置Java对象的属性,调用java对象的方法,同时能够自动 ...
- JavaScript(第二十天)【DOM操作表格及样式】
DOM在操作生成HTML上,还是比较简明的.不过,由于浏览器总是存在兼容和陷阱,导致最终的操作就不是那么简单方便了.本章主要了解一下DOM操作表格和样式的一些知识. 一.操作表格 <table& ...
- 团队作业7——第二次项目冲刺(Beta版本计划及安排)
Beta版本冲刺 需要改进完善的功能 1.寻找BUG.并解决问题 2.界面的优化 下一阶段新增的功能' 1.个人信息头像上传 2.头像裁剪功能 需要改进的团队分工 1.之前产品的主要工作 ...
- 下载文件downloadFile
public static void downLoadFile(InputStream inStream, String fileName) { if (StringUtils.isBlank(fil ...
- 201621123031 《Java程序设计》第2周学习总结
Week02-Java基本语法与类库 1. 本周学习总结 本周讲了Java的基本数据类型,主要分为八类(byte,short,int,long,double,float,char,boolean),其 ...
- listview、gradview滚动到最后时,滑动至顶部
listview.gradview滑动顶端.底部的判断及底部滑动至顶端 mPhotoWall.setOnScrollListener(new AbsListView.OnScrollListener( ...
- python之路--day15--常用模块之logging模块
常用模块 1 logging模块 日志级别:Noset (不设置) Debug---(调试信息)----也可用10表示 Info--(消息信息)----也可用20表示 Warning---(警告信息) ...
- 关于kali linux 2.0的vmware tools的安装问题
在安装好kali linux 2.0 后,首先要做的就是添加源并更新系统,否则会出现软件定位问题. 在kali 2.0中,vmware tools已经不能使用了,官方放了一个工具下载安装就好. 添加源 ...
- SQL Server 实现类似C#中 PadLeft功能
USE [Test] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO --@column 表示字段或者常量,@paddingChar 表示 补位 ...