CF940F Machine Learning

思路

带修莫队的题目
找答案可以直接暴力
因为答案是(O(sqrt{n}))级别的
懒得证明了

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;
int L,R,T,a[200100],b[200100],ans[200100],num_cnt,color[200100],times[200100],sz,belong[200100],n,m,Acnt,Qcnt;
map<int,int> M;
struct Query{
    int l,r,t,id;
    bool operator < (const Query & b) const {
        return (belong[l]==belong[b.l])?(belong[r]==belong[b.r]?t<b.t:belong[r]<belong[b.r]):belong[l]<belong[b.l];
    }
}Q[200100];
struct Modi{
    int pos,before,after;
}A[200100];
void init(void){
    sz=pow(n,0.666666);
    for(int i=1;i<=n;i++)
        belong[i]=(i-1)/sz+1;
}
int getans(void){
    for(int i=1;1;i++)
        if(times[i]<=0)
            return i;
}
void moveT(int t,int opt){
    if(opt==1){
        if(A[t].pos>=L&&A[t].pos<=R){
            times[color[A[t].before]]--;
            color[A[t].before]--;
            times[color[A[t].before]]++;
            times[color[A[t].after]]--;
            color[A[t].after]++;
            times[color[A[t].after]]++;
        }
        a[A[t].pos]=A[t].after;
    }
    else{
        if(A[t].pos>=L&&A[t].pos<=R){
            times[color[A[t].after]]--;
            color[A[t].after]--;
            times[color[A[t].after]]++;
            times[color[A[t].before]]--;
            color[A[t].before]++;
            times[color[A[t].before]]++;
        }
        a[A[t].pos]=A[t].before;
    }
    T+=opt;
}
void moveL(int opt){
    if(opt==1){
        times[color[a[L]]]--;
        color[a[L]]--;
        times[color[a[L]]]++;
        L++;
    }
    else{
        L--;
        times[color[a[L]]]--;
        color[a[L]]++;
        times[color[a[L]]]++;
    }
}
void moveR(int opt){
    if(opt==1){
        R++;
        times[color[a[R]]]--;
        color[a[R]]++;
        times[color[a[R]]]++;
    }
    else{
        times[color[a[R]]]--;
        color[a[R]]--;
        times[color[a[R]]]++;
        R--;
    }
}
int main(){
    scanf("%d %d",&n,&m);
    init();
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if(!M[a[i]])
            M[a[i]]=++num_cnt;
        a[i]=b[i]=M[a[i]];
    }
    for(int i=1;i<=m;i++){
        int opt,x,y;
        scanf("%d %d %d",&opt,&x,&y);
        if(opt==1){
            ++Qcnt;
            Q[Qcnt].id=Qcnt;
            Q[Qcnt].l=x;
            Q[Qcnt].r=y;
            Q[Qcnt].t=Acnt;
        }
        else{
            ++Acnt;
            A[Acnt].pos=x;
            if(!M[y])
                M[y]=++num_cnt;
            y=M[y];
            A[Acnt].before=b[x];
            A[Acnt].after=y;
            b[x]=y;
        }
    }
    sort(Q+1,Q+Qcnt+1);
    L=1;
    R=0;
    T=0;
    times[0]=num_cnt;
    for(int i=1;i<=Qcnt;i++){
        while(L>Q[i].l)
            moveL(-1);
        while(R<Q[i].r)
            moveR(1);
        while(L<Q[i].l)
            moveL(1);
        while(R>Q[i].r)
            moveR(-1);
        while(T<Q[i].t)
            moveT(T+1,1);
        while(T>Q[i].t)
            moveT(T,-1);
        ans[Q[i].id]=getans();
    }
    for(int i=1;i<=Qcnt;i++)
        printf("%d
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/dreagonm/p/10894631.html