CF940F Machine Learning (带修改莫队)
题目链接
https://codeforces.com/contest/940/problem/F
题意
给出n个数字,q个询问;
每次询问有两种类型,一种是询问区间,一种是单体修改;
定义Ci为区间里数字 i 出现的次数,求Ci数组的mex
#include<bits/stdc++.h>
using namespace std;
const int maxx = 2e5+10;
struct qnode
{
int l,r,t,id;
}e[maxx];
struct cnode
{
int p,pre,suc;
}c[maxx];
int a[maxx],b[maxx],ans[maxx];
int mx[maxx],sum[maxx];
int tot,siz;
int l,r,t;
map<int,int>ma;
bool cmp(qnode a,qnode b)
{
if(a.l/siz!=b.l/siz)return a.l<b.l;
if(a.r/siz!=b.r/siz)return a.r<b.r;
return a.t<b.t;
}
void add(int x,int c)
{
mx[sum[x]]--;
sum[x]+=c;
mx[sum[x]]++;
}
void change(int x,int y)
{
if(l<=x&&x<=r)
{
add(y,1);
add(a[x],-1);
}
a[x]=y;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
siz=pow(n,2.0/3);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(!ma[a[i]])ma[a[i]]=++tot; //离散化
a[i]=b[i]=ma[a[i]];
}
int t1=0,t2=0;
int op,x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
t1++;
e[t1].l=x,e[t1].r=y;
e[t1].id=t1,e[t1].t=t2;
}
else
{
t2++;
if(!ma[y])ma[y]=++tot;
c[t2].p=x;
c[t2].pre=b[x];
c[t2].suc=b[x]=ma[y];
}
}
sort(e+1,e+1+t1,cmp);
l=1,r=0,t=0;
for(int i=1;i<=t1;i++)
{
while(l<e[i].l)add(a[l++],-1);
while(l>e[i].l)add(a[--l],1);
while(r<e[i].r)add(a[++r],1);
while(r>e[i].r)add(a[r--],-1);
while(t<e[i].t)t++,change(c[t].p,c[t].suc);
while(t>e[i].t)change(c[t].p,c[t].pre),t--;
int num=1;
while(mx[num])num++;
ans[e[i].id]=num;
}
for(int i=1;i<=t1;i++)
printf("%d\n",ans[i]);
return 0;
}