题面

luogu

题解

  • 什么是启发式合并?

    小的合并到大的上面

    复杂度\(O(nlogn)\)

这题颜色的修改,即是两个序列的合并

考虑记录每个序列的\(size\)

小的合并到大的

存序列用链表

但是有一种情况,

\(x->y\)

\(siz[x] > siz[y]\)

这个时候我们可以新建一个\(f\)数组,存一个真实颜色

碰到这种情况时,\(swap(f[x], f[y])\)

合并即是\(f[x]->f[y]\)

Code

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define LL long long
  4. #define RG register
  5. using namespace std;
  6. template<class T> inline void read(T &x) {
  7. x = 0; RG char c = getchar(); bool f = 0;
  8. while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1;
  9. while (c >= '0' && c <= '9') x = x*10+c-48, c = getchar();
  10. x = f ? -x : x;
  11. return ;
  12. }
  13. template<class T> inline void write(T x) {
  14. if (!x) {putchar(48);return ;}
  15. if (x < 0) x = -x, putchar('-');
  16. int len = -1, z[20]; while (x > 0) z[++len] = x%10, x /= 10;
  17. for (RG int i = len; i >= 0; i--) putchar(z[i]+48);return ;
  18. }
  19. const int N = 1e6+10;
  20. int c[N], ans;
  21. int f[N], nxt[N], last[N], st[N], siz[N];
  22. void merge(int x, int y) {//x合并到y上
  23. for (int i = last[x]; i; i = nxt[i]) ans -= (c[i-1] == y) + (c[i+1] == y);
  24. for (int i = last[x]; i; i = nxt[i]) c[i] = y;
  25. nxt[st[x]] = last[y], last[y] = last[x], siz[y] += siz[x];
  26. last[x] = siz[x] = st[x] = 0;
  27. }
  28. int main() {
  29. int n, m;
  30. read(n), read(m);
  31. for (int i = 1; i <= n; i++) {
  32. read(c[i]);
  33. ans += c[i] != c[i-1];
  34. if (!last[c[i]]) st[c[i]] = i, f[c[i]] = c[i];
  35. nxt[i] = last[c[i]], last[c[i]] = i, siz[c[i]]++;
  36. }
  37. while (m--) {
  38. int opt; read(opt);
  39. if (opt == 2) printf("%d\n", ans);
  40. else {
  41. int x, y;
  42. read(x), read(y);
  43. if (x == y) continue;
  44. if (siz[f[x]] > siz[f[y]]) swap(f[x], f[y]);
  45. if (!siz[f[x]]) continue;
  46. merge(f[x], f[y]);
  47. }
  48. }
  49. return 0;
  50. }

洛谷 P3201 [HNOI2009]梦幻布丁(启发式合并)的更多相关文章

  1. 洛谷P3201 [HNOI2009]梦幻布丁 [链表,启发式合并]

    题目传送门 梦幻布丁 题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输 ...

  2. 洛谷P3201 [HNOI2009]梦幻布丁(链表 + 启发式合并)

    题目链接 给出 \(n\) 个布丁,每个补丁都有其颜色.现在有 \(m\) 次操作,每次操作将第 \(x_i\) 种颜色全部变为第 \(y_i\) 种颜色. 操作中可能会插入询问,回答目前总共有多少段 ...

  3. 洛谷P3201 [HNOI2009]梦幻布丁

    题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...

  4. 洛谷 3201 [HNOI2009]梦幻布丁 解题报告

    3201 [HNOI2009]梦幻布丁 题目描述 \(N\)个布丁摆成一行,进行\(M\)次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为\(1,2,2 ...

  5. bzoj 1483: [HNOI2009]梦幻布丁 启发式合并vector

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description N个 ...

  6. P3201 [HNOI2009]梦幻布丁

    题目描述 N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. 输入输出格式 输入格式: 第 ...

  7. luogu P3201 [HNOI2009]梦幻布丁

    传送门 先考虑暴力,显然每次是把一个位置集合和另一个集合合并,同时维护答案,合并的过程中如果两个集合每有一对元素相邻,答案就减1 优化暴力的话,说到合并,怎么能不想起启发式合并呢?每次把一个大小小的集 ...

  8. bzoj 1483 [HNOI2009]梦幻布丁(链表+启发式合并)

    1483: [HNOI2009]梦幻布丁 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1818  Solved: 761[Submit][Status ...

  9. BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )

    把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...

随机推荐

  1. [C++] right value reference

    the advantage of  right value reference: Memory Optimization save memory copy

  2. LA4794 分享巧克力

    Sharing Chocolate Chocolate in its many forms is enjoyed by millions of people around the world ever ...

  3. tp5 select回显

    <select name="role_id" id="" class="form-control" required> {vol ...

  4. $.ajax()函数

    一般在前端html和服务器交互,又要异步提交表单时,我们通常会用到$.ajax(){}函数,这是封装到ajax里的一个函数,相比于XMLHTTPRequest做页面局部刷新更方便,但最终还是使用的XM ...

  5. vscode安装dlv插件报错:There is no tracking information for the current branch.

    vscode安装dlv插件报错:There is no tracking information for the current branch. https://blog.csdn.net/a7859 ...

  6. HUST软测1504班第6周小组作业成绩

    说明 本次公布的成绩为第6周小组作业的结果: 第6周小组作业:WordCount(详情见毕博平台) 如果同学对作业结果存在异议,可以: 在毕博平台讨论区的第6周作业第在线答疑区发帖申诉. 或直接在博客 ...

  7. Spring5源码解析-论Spring DispatcherServlet的生命周期

    Spring Web框架架构的主要部分是DispatcherServlet.也就是本文中重点介绍的对象. 在本文的第一部分中,我们将看到基于Spring的DispatcherServlet的主要概念: ...

  8. [GO]使用select实现斐波那契

    package main import "fmt" func fibonacci(ch chan <- int, quit <- chan bool) { x, y : ...

  9. CodeForces 289B Polo the Penguin and Matrix (数学,中位数)

    题意:给定 n * m 个数,然后每次只能把其中一个数减少d, 问你能不能最后所有的数相等. 析:很简单么,首先这个矩阵没什么用,用一维的存,然后找那个中位数即可,如果所有的数减去中位数,都能整除d, ...

  10. ecshop后台登录频繁自动退出问题终极解决方法集锦

    ecshop后台登录后,有时候会自动退出,而且还会很频繁,有的是后台操作两下就莫名退出了,有的是恰好三分钟左右登出.这让管理员很恼火,严重影响了后台使用.对于这一问题,网络上可给的解决方法各有不同.千 ...