1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include <bits/stdc++.h> #define MAXN 2000005 using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+(ch^'0'); ch=getchar(); } return x*f; } int a[MAXN],pos[MAXN],n,m; struct Query{ int l,r,id; }q[MAXN]; inline bool operator < (const Query &A,const Query &B){ return pos[A.l]==pos[B.l]?A.r<B.r:pos[A.l]<pos[B.l]; } static int Ans[MAXN]; static int vis[MAXN]; static int Max[MAXN]; int ans,Size; struct node{ int pos,org; }stk[MAXN]; int top,f; inline void Update(int pos,int val){ if (f) stk[++top]=node{pos,Max[pos]}; Max[pos]=val; } inline void Add(int x){ vis[x]++; if (vis[x]>1) return ; if (x==0) { if (!vis[x+1]) ans=x+1; else ans=Max[x+1]+1; int R=Max[x+1]; Update(0,R);Update(R,0); return ; } int L=vis[x-1]?Max[x-1]:x,R=vis[x+1]?Max[x+1]:x; if (L==0) ans=R+1; Update(L,R);Update(R,L); } inline void Undo(){ for (register int i=top;i>=1;--i){ Max[stk[i].pos]=stk[i].org; } top=0; } inline int BruteForce(int l,int r){ ans=0; f=false; for (register int i=l;i<=r;++i){ Add(a[i]); } for (register int i=l;i<=r;++i){ Max[a[i]]=0,vis[a[i]]=0; } int temp=ans; ans=0; return temp; } inline int MoQueue(int i,int id){ int R=min(n,Size*id); int l=R,r=R-1; ans=0; memset(vis,0,sizeof(vis)); memset(Max,0,sizeof(Max)); top=0; while (pos[q[i].l]==id){ if (pos[q[i].l]==pos[q[i].r]){ Ans[q[i].id]=BruteForce(q[i].l,q[i].r); i++; continue; } f=false; while (r<q[i].r) Add(a[++r]); int temp=ans; f=true; while (l>q[i].l) Add(a[--l]); Ans[q[i].id]=ans; while (l<R) vis[a[l++]]--; Undo(); ans=temp; i++; } return i; } int main(){ n=read(),m=read(); Size=(int)(n/sqrt(m)); for (register int i=1;i<=n;++i){ a[i]=min(n+1,read()); pos[i]=(i-1)/Size+1; } for (register int i=1;i<=m;++i){ q[i].l=read(),q[i].r=read(),q[i].id=i; } sort(q+1,q+1+m); int ptr=1; for (register int i=1;i<=pos[n];++i){ ptr=MoQueue(ptr,i); } for (register int i=1;i<=m;++i){ printf("%d\n",Ans[i]); } }
|