[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个 ...
随机推荐
- 第2次作业:软件分析之Steam
1. 作业内容 1.1 介绍产品相关信息 你选择的产品是? 我选择的分析的软件为STEAM 为什么选择该产品作为分析? 在上述列表中的产品,除了王者荣耀,其他几项都是平时我使用较为频繁的软件,所以最初 ...
- centos7 下通过nginx+uwsgi部署django应用
1. 安装python3.6 1. 获取 wget https://www.python.org/ftp/python/3.6.2/Python-3.6.2.tgz tar -xzvf Python- ...
- maven添加oracle驱动
由于oracle商业版权问题,maven是不可以直接下载jar包的,所以.. 先将ojdbc14.jar放到用户目录,win7放到C:\Users\Administrator然后在cmd执行 ...
- const volatile同时限定一个类型int a = 10
const和volatile放在一起的意义在于: (1)本程序段中不能对a作修改,任何修改都是非法的,或者至少是粗心,编译器应该报错,防止这种粗心: (2)另一个程序段则完全有可能修改,因此编译器最好 ...
- Flask 扩展 HTTP认证
Restful API不保存状态,无法依赖Cookie及Session来保存用户信息,自然也无法使用Flask-Login扩展来实现用户认证.所以这里,我们就要介绍另一个扩展,Flask-HTTPAu ...
- Flask 学习 九 用户资料
资料信息 app/models.py class User(UserMixin,db.Model): #...... name = db.Column(db.String(64)) location ...
- AS 实机测试 ADB.exe 提示
adb fail to open error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037: 通常每 ...
- Python之旅.第三章.函数3.30
一.迭代器 1.什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来2.要想了解迭代器到底是什么?必须先了解一个概念,即什么是可迭代的对象?可迭代的对象:在python中,但凡内置 ...
- redis入门(01)redis的下载和安装
参考链接: 命令手册 : http://www.redis.net.cn/order/ 菜鸟教程: http://www.runoob.com/redis/redis-install.html 一.概 ...
- 敏捷项目需求拆解&发现用户故事
需求文档和敏捷中的Epic,User Story, Task之间是什么关系以及如何将需求文档转换成敏捷方式的描述,指导开发人员. 一直是很多公司团队比较困扰的问题,那么最近笔者为了解决这些问题,上了一 ...