Description

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

Input

第一行给出N,M表示布丁的个数和好友的操作次数. 第二行N个数A1,A2...An表示第i个布丁的颜色从第三行起有M行,对于每个操作,若第一个数字是1表示要对颜色进行改变,其后的两个整数X,Y表示将所有颜色为X的变为Y,X可能等于Y. 若第一个数字为2表示要进行询问当前有多少段颜色,这时你应该输出一个整数. 0

Output

针对第二类操作即询问,依次输出当前有多少段颜色.

Sample Input

4 3
1 2 2 1
2
1 2 1
2

Sample Output

3
1

HINT

Source

【分析】

转来的启发式合并的复杂度均摊分析:orzz

每次我们把短的合并到长的上面去,O(短的长度) 
咋看之下没有多大区别,
下面让我们看看均摊的情况:
1:每次O(N)
2:每次合并后,队列长度一定大于等于原来短的长度的两倍。
这样相当于每次合并都会让短的长度扩大一倍以上,
最多扩大logN次,所以总复杂度O(NlogN),每次O(logN)。
 
就是裸题了,搞一个链表把每种颜色段的开头位置记录下来,然后每次修改暴力修改+启发式合并就行。
还有就是记得把因为大小而导致错误的颜色用一个数组映射。
  1. /*
  2. 纳兰性德
  3. 人生若只如初见,何事秋风悲画扇。
  4. 等闲变却故人心,却道故人心易变。
  5. 骊山语罢清宵半,泪雨霖铃终不怨。
  6. 何如薄幸锦衣郎,比翼连枝当日愿。
  7. */
  8. #include <iostream>
  9. #include <cstdio>
  10. #include <algorithm>
  11. #include <cstring>
  12. #include <vector>
  13. #include <utility>
  14. #include <iomanip>
  15. #include <string>
  16. #include <cmath>
  17. #include <queue>
  18. #include <assert.h>
  19. #include <map>
  20. #include <ctime>
  21. #include <cstdlib>
  22. #include <stack>
  23. #define LOCAL
  24. const int MAXN = + ;
  25. const int INF = ;
  26. const int SIZE = ;
  27. const int MAXM = + ;
  28. const int maxnode = 0x7fffffff + ;
  29. using namespace std;
  30. struct Node{
  31. int num;
  32. Node *next;
  33. }*head[MAXM];//head为表头
  34. int cnt[MAXM], rem[MAXM], data[MAXM];
  35. int tot, n, m;
  36.  
  37. //在链表中加入颜色为x的节点
  38. void add(int x, int d){//d代表位置
  39. if (cnt[x] == ){
  40. head[x] = new Node;
  41. head[x]->num = d;
  42. head[x]->next = NULL;
  43. }else{
  44. //在表头插入
  45. Node *p = new Node;
  46. p->num = d;
  47. p->next = head[x];
  48. head[x] = p;
  49. }
  50. }
  51. void init(){
  52. tot = ;//记录颜色的总数
  53. memset(cnt, , sizeof(cnt));//记录颜色的数量
  54. scanf("%d%d", &n, &m);
  55. //for (int i = 1; i <= n; i++) rem[i] = i;
  56. data[] = -INF;
  57. for (int i = ; i <= n; i++){
  58. scanf("%d", &data[i]);//输入颜色
  59. if (data[i] != data[i - ]) tot++;
  60. cnt[data[i]]++;
  61. add(data[i], i);
  62. rem[data[i]] = data[i];//防错数组初始化
  63. }
  64.  
  65. }
  66. //将a颜色变成b颜色
  67. void change(int a, int b){
  68. //不要搞错了是比较正确颜色的个数
  69. if (cnt[rem[a]] > cnt[rem[b]]) swap(rem[a], rem[b]);
  70. a = rem[a];//总是让颜色数量少的变成多的
  71. b = rem[b];
  72. if (cnt[a] == ) return;
  73. cnt[b] += cnt[a];
  74. cnt[a] = ;
  75. Node *cur;
  76. for (cur = head[a]; cur != NULL; cur = cur->next){
  77. if (data[cur->num + ] == b) tot--;
  78. if (data[cur->num - ] == b) tot--;
  79. }
  80. for (cur = head[a]; cur->next != NULL; cur = cur->next) data[cur->num] = b;
  81. data[cur->num] = b;
  82. //最后将a插在b后面
  83. cur->next = head[b];
  84. head[b] = head[a];
  85. }
  86. void work(){
  87. for (int i = ; i <= m; i++){
  88. int t, a, b;
  89. scanf("%d", &t);
  90. if (t == ) printf("%d\n", tot);
  91. else{
  92. scanf("%d%d", &a, &b);
  93. if (a == b) continue;//两种颜色相同
  94. change(a, b);
  95. }
  96. }
  97. //for (int i = 1; i <= n; i++) printf("%d", data[i]);
  98. }
  99.  
  100. int main(){
  101.  
  102. init();
  103. work();
  104. return ;
  105. }

【BZOJ1483】【链表启发式合并】梦幻布丁的更多相关文章

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

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

  2. 【BZOJ1483】[HNOI2009]梦幻布丁 链表+启发式合并

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

  3. 【链表+启发式合并】Bzoj1483 [HNOI2009] 梦幻布丁

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

  4. BZOJ1483 [HNOI2009]梦幻布丁 【链表 + 启发式合并】

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

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

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

  6. BZOJ 1483: [HNOI2009]梦幻布丁 [链表启发式合并]

    1483: [HNOI2009]梦幻布丁 题意:一个带颜色序列,一种颜色合并到另一种,询问有多少颜色段 一种颜色开一个链表,每次遍历小的合并到大的里,顺带维护答案 等等,合并方向有规定? 令col[x ...

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

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...

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

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

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

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

随机推荐

  1. java基础 (六)面向对象(一)

    这里有我之前上课总结的一些知识点以及代码大部分是老师讲的笔记 个人认为是非常好的,,也是比较经典的内容,真诚的希望这些对于那些想学习的人有所帮助! 由于代码是分模块的上传非常的不便.也比较多,讲的也是 ...

  2. http 协议的过程

    当你输入某个网址的时候发生了什么? 首先:你该知道 a.http协议是应用层协议,他是浏览器像服务器请求网页,服务器返回网页的过程,他是基于tcp协议的. 1.假设随便输入输入域名 http://ww ...

  3. 内存模型(memory models)和命名空间(namespace)

    继续<C++ premier plus > 先来解释一下scope和linkage,所谓scope,是指变量的作用范围,所谓linkage,是指变量能否在不同文件中共享 1,自动变量(au ...

  4. 京东集团副总裁李大学:像CEO一样思考 - Dancen的专栏 - 博客频道 - CSDN.NET

    京东集团副总裁李大学:像CEO一样思考 - Dancen的专栏 - 博客频道 - CSDN.NET 京东集团副总裁李大学:像CEO一样思考

  5. maven常用插件配置

    1.maven-jar-plugin插件 <!-- 排除资源文件中的properties文件,不需要打到jar中,后面通过assembly插件打包到conf目录中 --><plugi ...

  6. 小试牛刀——python接口测试小框架

    用例设计: 执行用例代码: # -*- coding: UTF-8 -*-import xlrd,logging,urllib,urllib2,json,sysfrom pylsy import py ...

  7. java如何遍历hashMap

    通过Map的entrySet方法.将返回一个set集合.然后遍历这个set集合: package com.howlaa.day04; import java.util.HashMap; import ...

  8. 看个人思路吧,清晰的话就简单 CodeForces 271A - Beautiful Year

    It seems like the year of 2013 came only yesterday. Do you know a curious fact? The year of 2013 is ...

  9. 语音控制的tab选项卡

    前端开发whqet,csdn,王海庆,whqet,前端开发专家 ladies and 乡亲们,程序猿同志们,周末仍然坚守工作岗位,或者学习不辍的童鞋们,福音来了. 语音识别高不高端.难不难? 今天给大 ...

  10. 回收InnoDB表空间

    以下论述均假定innodb_file_per_table开启 先用常规optimize回收: mysql> select count(*) from t; +----------+ | coun ...