P3201 [HNOI2009] 梦幻布丁——线段树合并 set启发式合并

[HNOI2009] 梦幻布丁

题目描述

n 个布丁摆成一行,进行 m 次操作。每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色。

例如,颜色分别为 1,2,2,1 的四个布丁一共有 3 段颜色.

输入格式

第一行是两个整数,分别表示布丁个数 n 和操作次数 m
第二行有 n 个整数,第 i 个整数表示第 i 个布丁的颜色 ai
接下来 m 行,每行描述一次操作。每行首先有一个整数 op 表示操作类型:

  • op=1,则后有两个整数 x,y,表示将颜色 x 的布丁全部变成颜色 y
  • op=2,则表示一次询问。

输出格式

对于每次询问,输出一行一个整数表示答案。

样例 #1

样例输入 #1

4 3
1 2 2 1
2
1 2 1
2

样例输出 #1

3
1

提示

样例 1 解释

初始时布丁颜色依次为 1,2,2,1,三段颜色分别为 [1,1],[2,3],[4,4]
一次操作后,布丁的颜色变为 1,1,1,1,只有 [1,4] 一段颜色。

数据规模与约定

对于全部的测试点,保证 1n,m1051ai,x,y106

提示

请注意,不保证颜色的编号不大于 n,也不保证 xym 不是颜色的编号上限。

分析

线段树合并模板,注意不要自己合并自己。

又:链表启发式合并

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100,M=1e6+100;
struct segtree
{
int lc,rc,val;
int lef,rig;
}s[N<<6];
struct col
{
int x,y,op;
}q[N];
int n,m,root[M],tot;
int h[M],ans;
void pushup(int i)
{
s[i].lef=(s[i].lc>0)?(s[s[i].lc].lef):(s[s[i].rc].lef);
s[i].rig=(s[i].rc>0)?(s[s[i].rc].rig):(s[s[i].lc].rig);
s[i].val=s[s[i].lc].val+s[s[i].rc].val-(s[s[i].rc].lef==s[s[i].lc].rig+1);
}
void upd(int &i,int l,int r,int x)
{
if(!i)i=++tot;
if(l==r)
{
s[i].lef=s[i].rig=l;
s[i].val=1;
return ;
}
int mid=(l+r)>>1;
if(x<=mid)
upd(s[i].lc,l,mid,x);
else
upd(s[i].rc,mid+1,r,x);
pushup(i);
}
void merg(int &i,int &j,int l,int r)
{
if(i==0 || j==0)
{
i+=j;
return ;
}
if(l==r)
{
s[i].val=1;
s[i].lef=s[i].rig=l;
return ;
}
int mid=(l+r)>>1;
merg(s[i].lc,s[j].lc,l,mid);
merg(s[i].rc,s[j].rc,mid+1,r);
pushup(i);
}
void init()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",h+i);
for(int i=1;i<=n;++i)
{
ans=ans-s[root[h[i]]].val;
upd(root[h[i]],1,n,i);
ans=ans+s[root[h[i]]].val;
}
}
void work()
{
while(m--)
{
int opt,x,y;
scanf("%d",&opt);
if(opt==1)
{
scanf("%d%d",&x,&y);
if(x==y)continue;
ans=ans-s[root[x]].val-s[root[y]].val;
merg(root[y],root[x],1,n);
root[x]=0;
ans+=s[root[y]].val;
}
else
printf("%d\n",ans);
}
}
int main()
{
init();
work();
return 0;
}
posted @   Glowingfire  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示