翻译:
给出一个长度为n(n<=100000)的序列,序列中每个数a[i]<=10^9 设c[i]表示第i种数出现的次数
q(q<=100000)次询问,询问共有两种 第一种 1 x y 表示求序列中x~y
c[i]的mex。mex表示最小的没有出现过的值(不包括0) 第二种 2 x y 表示把序列中第x位的数替换为y
题解
治数据结构学傻系列这是
万能的莫队
首先有一个性质,我们可以观察出结果一定不会大于1000,所以处理答案的时候暴力枚举就好。为什么?如果每个数恰好出现要求的次数,那么1加到1000也是超过100000的了,所以答案不会超过1000
于是用一个带修改的莫队水一下就OK了
排序打错TLE难受
复习了一发带修莫队以及莫队2333
/*
翻译:
给出一个长度为n(n<=100000)的序列,序列中每个数a[i]<=10^9
设c[i]表示第i种数出现的次数
q(q<=100000)次询问,询问共有两种
第一种 1 x y 表示求序列中x~y c[i]的mex。mex表示最小的没有出现过的值(不包括0)
第二种 2 x y 表示把序列中第x位的数替换为y
*/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
map<int,int> q;
int val[210000],len;
int l,r,t;
struct pck{int p,c,las;}ch[210000];int chlen;
struct ask
{
int l,r,t,op;
}A[210000];int n,m,alen;
int block,pos[210000];
bool cmp(ask n1,ask n2)
{
if(pos[n1.l]!=pos[n2.l])return pos[n1.l]<pos[n2.l];
if(pos[n1.r]!=pos[n2.r])return pos[n1.r]<pos[n2.r];
return n1.t<n2.t;
}
int vis[210000];//sum[i]的出现次数
int col[210000],las[210000],answer[210000],ans;//las[i]表示第i个位置上一次的颜色
int sum[210000];//每种数出现了多少次
void upd_col(int now,int c)
{
if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]--,vis[sum[col[now]]]++;
col[now]=c;
if(now>=l && now<=r)vis[sum[col[now]]]--,sum[col[now]]++,vis[sum[col[now]]]++;
}
void del(int now)
{
vis[sum[col[now]]]--;
sum[col[now]]--;
vis[sum[col[now]]]++;
}
void add(int now)
{
vis[sum[col[now]]]--;
sum[col[now]]++;
vis[sum[col[now]]]++;
}
int gtans(){for(int i=1;;i++)if(vis[i]==0)return i;}
int main()
{
scanf("%d%d",&n,&m);
block=ceil(pow(n,2.0/3));
for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1;
for(int i=1;i<=n;i++)
{
scanf("%d",&col[i]);
val[++len]=col[i];las[i]=col[i];
}
for(int i=1;i<=m;i++)
{
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
if(op==1)
{
alen++;
A[alen].l=u;A[alen].r=v;A[alen].t=chlen;
A[alen].op=i-chlen;
}
else
{
chlen++;ch[chlen].p=u;ch[chlen].c=v;
ch[chlen].las=las[u];las[u]=v;
val[++len]=v;
}
}
sort(val+1,val+1+len);
len=unique(val+1,val+1+len)-val-1;
for(int i=1;i<=len;i++)q[val[i]]=i;
for(int i=1;i<=chlen;i++)ch[i].las=q[ch[i].las],ch[i].c=q[ch[i].c];
for(int i=1;i<=n;i++)col[i]=q[col[i]];
sort(A+1,A+1+alen,cmp);
l=A[1].l,r=A[1].r,t=A[1].t;
for(int i=1;i<=A[1].t;i++)col[ch[i].p]=ch[i].c;
for(int i=A[1].l;i<=A[1].r;i++)
{
vis[sum[col[i]]]--;
sum[col[i]]++;
vis[sum[col[i]]]++;
}
for(int i=1;;i++)if(vis[i]==0){answer[A[1].op]=i;break;}
for(int i=2;i<=alen;i++)
{
while(t<A[i].t)t++,upd_col(ch[t].p,ch[t].c);
while(t>A[i].t)upd_col(ch[t].p,ch[t].las),t--;
while(l<A[i].l)del(l++);
while(l>A[i].l)add(--l);
while(r<A[i].r)add(++r);
while(r>A[i].r)del(r--);
answer[A[i].op]=gtans();
//for(int j=l;j<=r;j++)printf("%d ",col[j]);
}
for(int i=1;i<=alen;i++)printf("%d\n",answer[i]);
return 0;
}