[bzoj1483]梦幻布丁
2024-10-20 07:54:09
对于每一个颜色用一个链表存储,并记录下: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 }
最新文章
- centos6.5安装elasticsearch
- Docker 容器部署 Consul 集群
- Spring - constructor-arg和property
- 【12-JDBC编程】
- javascript运算符——逻辑运算符
- Javascript的delete
- iostart命令
- mongodb远程连接以及备份、还原、导出、导入
- oracle随笔(转)
- 【转】iOS开发入门:Xcode常用快捷键
- java多个listener监听
- Clojure操作mysql
- RTB撕开黑盒子 Part 0:Pacing: is everyone doing it wrong?
- 第八讲:I/O虚拟化
- 使用hive客户端java api读写hive集群上的信息
- MyBatis + MySQL返回插入的主键id
- 【Android】Android Studio3.1 Mac版本设置项目桌面icon
- Element UI toggleRowExpansion用法
- JavaScript 系列博客(二)
- 阿里云centos 开启ipv6