1. 程式人生 > >[ 帶修改莫隊 ] Codeforces940F Machine Learning

[ 帶修改莫隊 ] Codeforces940F Machine Learning

直接上帶修改莫隊。維護 mex 只需要對權值分塊,每塊記錄出現次數,查詢時找到第一個有數沒出現過的塊,然後在塊中列舉。

#include<bits/stdc++.h>
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void Read(int& x){
    char c=nc();
    for
(;c<'0'||c>'9';c=nc()); for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc()); } #define fi first #define se second const int N=100010; const int Sn=320; struct Node{ int l,r,t; }c[N]; struct node{ int pre; int t,x,y; }d[N]; pair<int,int> A[N<<1]; int
cc; int tot,cnt; int Ans[N]; int a[N],aa[N]; int x,y; int w,k,n,q,m,s; int L=1,R; int b[N]; int num[Sn],l[Sn],r[Sn],sum[Sn][N]; int Cnt[N]; inline bool Cmp(Node x,Node y){ return b[x.l]<b[y.l]||(b[x.l]==b[y.l]&&b[x.r]<b[y.r])||(b[x.l]==b[y.l]&&b[x.r]==b[y.r]&&x.t<y.t); } inline
bool Cmp1(node x,node y){ return x.t<y.t; } inline void add(int x){ if(!(sum[b[x]][x]++))num[b[x]]++; } inline void del(int x){ if(!(--sum[b[x]][x]))num[b[x]]--; } inline void Add(int x){ if(Cnt[x])del(Cnt[x]);add(++Cnt[x]); } inline void Del(int x){ del(Cnt[x]);if((--Cnt[x]))add(Cnt[x]); } inline int Query(){ int i=1; for(;i<=b[n];i++) if(num[i]!=r[i]-l[i]+1)break; for(int j=l[i];j<=r[i];j++) if(!sum[i][j])return j; } int main(){ Read(n);Read(q); for(int i=1;i<=n;i++)Read(A[i].fi),A[i].se=i; for(int i=1;i<=q;i++){ Read(k);Read(x);Read(y); if(k==1){ c[++cnt].l=x;c[cnt].r=y;c[cnt].t=i; }else{ d[++tot].x=x;d[tot].y=y;d[tot].t=i; A[n+tot].fi=y;A[n+tot].se=n+tot; } } sort(A+1,A+n+tot+1); for(int i=1;i<=n+tot;i++){ if(A[i].fi!=A[i-1].fi)w++; if(A[i].se<=n)a[A[i].se]=w;else d[A[i].se-n].y=w; } s=pow(n,2.0/3.0); for(int i=1;i<=n;i++)b[i]=(i-1)/s+1; sort(c+1,c+cnt+1,Cmp); sort(d+1,d+tot+1,Cmp1); s=sqrt(n); for(int i=1;i<=n;i++)b[i]=(i-1)/s+1,r[b[i]]=i; for(int i=n;i;i--)l[b[i]]=i; int j=0; for(int i=1;i<=cnt;i++){ while(j<tot&&d[j+1].t<c[i].t){ j++; if(d[j].x>=L&&d[j].x<=R)Del(a[d[j].x]),Add(d[j].y); d[j].pre=a[d[j].x]; a[d[j].x]=d[j].y; } while(j&&d[j].t>c[i].t){ if(d[j].x>=L&&d[j].x<=R)Del(d[j].y),Add(d[j].pre); a[d[j].x]=d[j].pre; j--; } while(c[i].r>R)Add(a[++R]); while(c[i].l<L)Add(a[--L]); while(c[i].r<R)Del(a[R--]); while(c[i].l>L)Del(a[L++]); Ans[c[i].t]=Query(); } for(int i=1;i<=q;i++) if(Ans[i])printf("%d\n",Ans[i]); return 0; }