对于每一个颜色用一个链表存储,并记录下:1.当前某种颜色的真实颜色;2.这种颜色的数量(用于启发式合并的判断);3.当前答案(即有几段),然后对于每一个操作简单处理一下就行了。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1000005
4 int n,m,ans,p,x,y,head[N],tru[N],sum[N],nex[N],last[N],a[N];
5 void merge(int x,int y){
6 for(int i=head[x];i!=-1;i=nex[i])ans-=(a[i-1]==y)+(a[i+1]==y);
7 for(int i=head[x];i!=-1;i=nex[i])a[i]=y;
8 sum[y]+=sum[x];
9 nex[last[y]]=head[x];
10 last[y]=last[x];
11 head[x]=-1;
12 sum[x]=last[x]=0;
13 }
14 int main(){
15 scanf("%d%d",&n,&m);
16 memset(head,-1,sizeof(head));
17 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
18 for(int i=n;i;i--){
19 if (a[i]!=a[i-1])ans++;
20 tru[a[i]]=a[i];
21 if (head[a[i]]==-1)last[a[i]]=i;
22 sum[a[i]]++;
23 nex[i]=head[a[i]];
24 head[a[i]]=i;
25 }
26 for(int i=1;i<=m;i++){
27 scanf("%d",&p);
28 if (p==2)printf("%d\n",ans);
29 else{
30 scanf("%d%d",&x,&y);
31 if (sum[tru[x]]>sum[tru[y]])swap(tru[x],tru[y]);
32 if ((x!=y)&&(sum[tru[x]]))merge(tru[x],tru[y]);
33 }
34 }
35 }

最新文章

  1. centos6.5安装elasticsearch
  2. Docker 容器部署 Consul 集群
  3. Spring - constructor-arg和property
  4. 【12-JDBC编程】
  5. javascript运算符——逻辑运算符
  6. Javascript的delete
  7. iostart命令
  8. mongodb远程连接以及备份、还原、导出、导入
  9. oracle随笔(转)
  10. 【转】iOS开发入门:Xcode常用快捷键
  11. java多个listener监听
  12. Clojure操作mysql
  13. RTB撕开黑盒子 Part 0:Pacing: is everyone doing it wrong?
  14. 第八讲:I/O虚拟化
  15. 使用hive客户端java api读写hive集群上的信息
  16. MyBatis + MySQL返回插入的主键id
  17. 【Android】Android Studio3.1 Mac版本设置项目桌面icon
  18. Element UI toggleRowExpansion用法
  19. JavaScript 系列博客(二)
  20. 阿里云centos 开启ipv6

热门文章

  1. nodejs 安装 报错解决方案
  2. python os.walk处理树状目录结构的文件
  3. Linux命令查看内存、整体负载、端口查看、进程查看、vim编辑器(3)
  4. jquery-无缝滚动
  5. 【UE4 C++ 基础知识】&lt;13&gt; 多线程——TaskGraph
  6. 【UE4 C++】Actor 与 Component —— 创建、销毁
  7. Seata的一些概念
  8. 零基础入门Linux有什么好的学习方法吗?(超详细)
  9. 转:汇编中EBP寄存器和ESP寄存器的区别
  10. centos7 使用iptables