洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)
题面
题解
- 什么是启发式合并?
小的合并到大的上面
复杂度\(O(nlogn)\)
这题颜色的修改,即是两个序列的合并
考虑记录每个序列的\(size\)
小的合并到大的
存序列用链表
但是有一种情况,
\(x->y\)
\(siz[x] > siz[y]\)
这个时候我们可以新建一个\(f\)数组,存一个真实颜色
碰到这种情况时,\(swap(f[x], f[y])\)
合并即是\(f[x]->f[y]\)
Code
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
#define RG register
using namespace std;
template<class T> inline void read(T &x) {
x = 0; RG char c = getchar(); bool f = 0;
while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
x = f ? -x : x;
return ;
}
template<class T> inline void write(T x) {
if (!x) {putchar(48);return ;}
if (x < 0) x = -x, putchar('-');
int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
}
const int N = 1e6+10;
int c[N], ans;
int f[N], nxt[N], last[N], st[N], siz[N];
void merge(int x, int y) {//x合并到y上
for (int i = last[x]; i; i = nxt[i]) ans -= (c[i-1] == y) + (c[i+1] == y);
for (int i = last[x]; i; i = nxt[i]) c[i] = y;
nxt[st[x]] = last[y], last[y] = last[x], siz[y] += siz[x];
last[x] = siz[x] = st[x] = 0;
}
int main() {
int n, m;
read(n), read(m);
for (int i = 1; i <= n; i++) {
read(c[i]);
ans += c[i] != c[i-1];
if (!last[c[i]]) st[c[i]] = i, f[c[i]] = c[i];
nxt[i] = last[c[i]], last[c[i]] = i, siz[c[i]]++;
}
while (m--) {
int opt; read(opt);
if (opt == 2) printf("%d\n", ans);
else {
int x, y;
read(x), read(y);
if (x == y) continue;
if (siz[f[x]] > siz[f[y]]) swap(f[x], f[y]);
if (!siz[f[x]]) continue;
merge(f[x], f[y]);
}
}
return 0;
}
洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)的更多相关文章
- 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]
题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...
- 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)
题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...
- 洛谷P3201 [HNOI2009]梦幻布丁
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- 洛谷 3201 [HNOI2009]梦幻布丁 解题报告
3201 [HNOI2009]梦幻布丁 题目描述 \(N\)个布丁摆成一行,进行\(M\)次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为\(1,2,2 ...
- bzoj 1483: [HNOI2009]梦幻布丁 启发式合并vector
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MB[Submit][Status][Discuss] Description N个 ...
- P3201 [HNOI2009]梦幻布丁
题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...
- luogu P3201 [HNOI2009]梦幻布丁
传送门 先考虑暴力,显然每次是把一个位置集合和另一个集合合并,同时维护答案,合并的过程中如果两个集合每有一对元素相邻,答案就减1 优化暴力的话,说到合并,怎么能不想起启发式合并呢?每次把一个大小小的集 ...
- bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)
1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1818 Solved: 761[Submit][Status ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
随机推荐
- Fix “Could Not Find This Item” When Deleting in Windows 7
If you’ve been using Windows for as long as I have, you have probably run into your share of weird e ...
- [SoapUI] context.expand 和 groovyUtils.getXmlHolder 有什么不一样
context.expand 和 groovyUtils.getXmlHolder 有什么不一样?互相之间怎么转换 import com.eviware.soapui.support.GroovyUt ...
- java重载方法的二义性
http://blog.csdn.net/lavor_zl/article/details/40746813
- jquery UI datepicker汉化
由于近期工作需要,jquery ui的datepicker需要汉化,特此把代码贴在这$(function() { $.datepicker.regional["zh-CN"] = ...
- JavaScript词法作用域经典练习题
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...
- kalilinux-信息搜集
dns扫描: dnsenum --enum www.baidu.com --threads [number] 一次运行的线程数量 -r 递归查找 -d 允许你设置在WHOIS请求之间的时间延迟,单位为 ...
- 云存储上传控件(cloud2)-Xproer.HttpUploader7
版权所有 2009-2016 荆门泽优软件有限公司 保留所有权利 官方网站:http://www.ncmem.com/ 产品首页:http://www.ncmem.com/webapp/cloud2/ ...
- OpenCV 4 Android
OpenCV4Android Want a Quick Start link? Use this tutorial: “OpenCV for Android SDK”. 想要快速开始吗?使用这个教程: ...
- 编写高质量代码改善C#程序的157个建议——建议92:谨慎将数组或集合作为属性
建议92:谨慎将数组或集合作为属性 数组或集合作为属性会引起这样一个问题:如果属性是只读的,我们通常会认为它是不可用改变的,但如果将只读属性应用于数座或集合,而元素的内容和数量却仍旧可以随意改变.如下 ...
- 领域模型驱动设计(Domain Driven Design)入门概述 -----DDD 解释
软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 ...