区间mex,考虑离线按左端点排序
左端点右移时,这个数到它的下一个数之间的位置(作为右端点)的mex值全部与当前数取min
#include<bits/stdc++.h>
#define MAXN 200005
#define MX 200005
#define INF 0x3f3f3f3f
using namespace std; int n,m;
inline int read(){
char ch=getchar();
while(!isdigit(ch)) ch=getchar();
int rtn = 0;
while(isdigit(ch)) rtn = rtn*10 +ch-'0' , ch=getchar();
return rtn;
}
int a[MAXN];
int mex[MAXN],tag[MAXN<<2];
int nxt[MAXN],lst[MAXN];
struct t1{
int l,r,id;
bool operator < (const t1 &ano) const{
return l<ano.l;
}
}Q[MAXN];
int ans[MAXN];
void modify(int now,int l,int r,int L,int R,int v){
if(L<=l&&r<=R) return void(tag[now] = min(tag[now],v));
int mid = (l+r)>>1;
if(L<=mid) modify(now<<1,l,mid,L,R,v);
if(mid<R) modify(now<<1|1,mid+1,r,L,R,v);
}
int inqry(int now,int l,int r,int pos){
int rtn = tag[now];
if(l==r) return rtn = min(rtn,mex[l]);
int mid = (l+r)>>1;
if(pos<=mid) return min(rtn,inqry(now<<1,l,mid,pos));
else return min(rtn,inqry(now<<1|1,mid+1,r,pos));
}
int main(){
// freopen("1.in","r",stdin);
n=read(),m=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1,k=0;i<=n;++i){
tag[a[i]] = 1;
while(tag[k]) ++k;
mex[i] = k;
}
for(int i=0;i<MX;++i) lst[i] = n+1;
for(int i=n;i;--i) nxt[i] = lst[a[i]] , lst[a[i]] = i;
memset(tag,INF,sizeof tag);
for(int i=1;i<=m;++i) Q[i].l = read(),Q[i].r = read(),Q[i].id = i;
sort(Q+1,Q+m+1);
for(int i=1,now=1;i<=m;++i){
while(now<Q[i].l){
modify(1,1,n,now,nxt[now]-1,a[now]);
++now;
}
ans[Q[i].id] = inqry(1,1,n,Q[i].r);
}
for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
return 0;
}