codeforce940 F. Machine Learning 帶修莫隊
阿新 • • 發佈:2018-12-11
給定一個帶修改的序列,求一個區間中最小的未出現的數的個數
單點修改,區間查詢
任意離散化+帶修莫隊(可持續化,按時間程序記錄修改先後的值的版本)
#include<bits/stdc++.h> using namespace std; const int MAX=2e5+5; int n,m,cntq,cntc,cntid,block,a[MAX],now[MAX],vis[MAX],ans[MAX]; map<int,int>id; struct P { int l,r,t,ans; void is(int x1,int x2,int x3){l=x1;r=x2;t=x3;} }q[MAX]; struct Q { int pos,u,v,t; void is(int x1,int x2,int x3,int x4){pos=x1;u=x2;v=x3;t=x4;} }c[MAX]; inline bool cmp1(P& x1,P& x2) { if(x1.l/block!=x2.l/block) return x1.l<x2.l; if(x1.r/block!=x2.r/block) return x1.r<x2.r; return x1.t<x2.t; } inline bool cmp2(P& x1,P& x2){return x1.t<x2.t;} inline void add(int x,int d) { if(vis[x]>0)--ans[vis[x]]; vis[x]+=d; if(vis[x]>0)++ans[vis[x]]; } inline void change(int &x,int l,int r,int val) { if(c[x].v==0) return ; if(c[x].pos>=l&&c[x].pos<=r) { add(a[c[x].pos],-1); add(val,1); } a[c[x].pos]=val; } inline int sid(int x) { if(id[x]) return id[x]; return id[x]=++cntid; } int main() { int x,y,z; id.clear();cntq=cntid=0;memset(now,0,sizeof(now));memset(c,0,sizeof(c)); scanf("%d%d",&n,&m);block=pow(n,2.0/3); for(int i=1;i<=n;++i) {scanf("%d",&a[i]);now[i]=a[i]=sid(a[i]);} for(int i=1;i<=m;++i) { scanf("%d%d%d",&x,&y,&z); if(x==1) q[cntq++].is(y,z,i); else c[i].is(y,now[y],z=sid(z),i),now[y]=z; } sort(q,q+cntq,cmp1); int l=1,r=0,t=0; for(int i=0;i<cntq;++i) { while(r<q[i].r) add(a[++r],1); while(l<q[i].l) add(a[l++],-1); while(r>q[i].r) add(a[r--],-1); while(l>q[i].l) add(a[--l],1); while(t<q[i].t) ++t,change(t,l,r,c[t].v); while(t>q[i].t) change(t,l,r,c[t].u),--t; int k=1;while(ans[k]) ++k;q[i].ans=k; } sort(q,q+cntq,cmp2); for(int i=0;i<cntq;++i) printf("%d\n",q[i].ans); return 0; }