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;
}
posted @ 2020-03-11 00:10  灰灰烟影  阅读(173)  评论(0编辑  收藏  举报