Codeforces Round #466 (Div. 2) F. Machine Learning (带修莫队)

题意:

     一个数组,问某个区间里面,第一个没出现的所有数出现次数的出现次数正整数

思路:

     题意有点毒,第二次才读对。一读题就觉得,带修莫队就可以处理了,然后我们发现需要离散化,那么我们干脆在之前就把数字离散了,因为有修改,所以最多为2e5个数,这样就很好处理了。因为是出现次数的出现次数,所以最多只有不到500项,那么暴力从1找就行(我优化了寻找的过程反而不如暴力,果然还是我太菜了ORZ)

错误及反思:

    好像CF已经给你能inline的都inline了,所以我加不加inline时间都一样

代码:

#include<bits/stdc++.h>
using namespace std;
const int N = 200100;
int n,qus,blocks,block[N],a[N],tid=1,ans[N],num[N],tnum[N],ti=0,k,totq=0,last[N],totc=0;
map<int,int> mp;
struct Q{
    int l,r,tim,id;
}q[N];

bool cmp(Q a,Q b){
    if(block[a.l]==block[b.l]){
        if(block[a.r]==block[b.r])
            return a.tim<b.tim;
        return a.r<b.r;
    }
    return a.l<b.l;
}

struct C{
    int pos,to,bef;
}c[N];

void change(int x,int y){
    tnum[num[x]]--;
    num[x]+=y;
    tnum[num[x]]++;
}
int main(){
    scanf("%d%d",&n,&qus);
    blocks=pow(n,0.66666);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        block[i]=i/blocks+1;
        if(!mp[a[i]]) mp[a[i]]=tid++;
        a[i]=mp[a[i]];
        last[i]=a[i];
    }
    for(int i=0;i<qus;i++){
        scanf("%d",&k);
        if(k==1){
            scanf("%d%d",&q[totq].l,&q[totq].r);
            q[totq].id=totq;
            q[totq++].tim=totc;
        }
        else{
            scanf("%d%d",&c[totc].pos,&c[totc].to);
            if(!mp[c[totc].to]) mp[c[totc].to]=tid++;
            c[totc].to=mp[c[totc].to];
            c[totc].bef=last[c[totc].pos];
            last[c[totc].pos]=c[totc++].to;
        }
    }
    sort(q,q+totq,cmp);
    for(int i=0,l=1,r=0,ti=0;i<totq;i++){
        for(;ti<q[i].tim;ti++){
            if(l<=c[ti].pos&&r>=c[ti].pos){
                change(c[ti].bef,-1);
                change(c[ti].to,1);
            }
            a[c[ti].pos]=c[ti].to;
        }
        for(;ti>q[i].tim;ti--){
            if(l<=c[ti-1].pos&&r>=c[ti-1].pos){
                change(c[ti-1].bef,1);
                change(c[ti-1].to,-1);
            }
            a[c[ti-1].pos]=c[ti-1].bef;
        }
        for(;r<q[i].r;r++)
            change(a[r+1],1);
        for(;l>q[i].l;l--)
            change(a[l-1],1);
        for(;r>q[i].r;r--)
            change(a[r],-1);
        for(;l<q[i].l;l++)
            change(a[l],-1);
        ans[q[i].id]=1;
        while(tnum[ans[q[i].id]]) ans[q[i].id]++;
    }
    for(int i=0;i<totq;i++)
        printf("%d\n",ans[i]);
}

猜你喜欢

转载自blog.csdn.net/roll_keyboard/article/details/80442852