文件详细信息
本文件的大小为 1997 字节。
/*
## 题目大意
有一个长度为 $n$ 的数组 $a_1,a_2,\cdots,a_n$。$m$ 次询问,每次询问一个区间内最小没有出现过的自然数。
保证 $1 \le n,m \le 2 \times 10^5$,$0 \le a_i \le 10^9$。
*/
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
template<typename T>
void read(T&num){
int ch=getchar();
num=0;
while(ch<48||ch>57)ch=getchar();
while(ch>=48&&ch<=57)num=(num<<3)+(num<<1)+(ch^48),ch=getchar();
}
template<typename T>
void write(T a){
static int ch[20],cnt=0;
if(a==0)putchar('0');
while(a)ch[cnt++]=a%10|48,a/=10;
while(cnt)putchar(ch[--cnt]);
}
template<typename T>
void chkmin(T&a,const T b){
if(a>b)a=b;
}
const int maxn=200000,maxm=200000,maxtot=448;
int n,m,B,tot,a[maxn+1],b[maxn+1],mex,cur,tmp,belong[maxn+1],l[maxtot+1],r[maxtot+1],cnt[maxn+1];
struct OP{
int l,r,id;
}q[maxm+1];
bool operator<(const OP a,const OP b){
return belong[a.l]!=belong[b.l]?a.l<b.l:a.r>b.r;
}
int ans[maxm+1];
void del(const int x){
if(a[x]<mex&&--cnt[a[x]]==0)chkmin(cur,a[x]);
}
void add(const int x){
if(a[x]<mex)cnt[a[x]]++;
}
int main(){
read(n),read(m);
B=sqrt(n),tot=(n+B-1)/B;
for(int i=1;i<=n;i++)read(a[i]);
memcpy(b+1,a+1,sizeof(int)*n);
std::sort(b+1,b+n+1);
b[0]=-1;
for(int i=1;i<=n;i++)
if(b[i]>=b[i-1]+2){
mex=b[i-1]+1;
break;
}
if(!mex)mex=b[n]+1;
for(int i=1;i<=n;i++)
if(a[i]<mex)
cnt[a[i]]++;
for(int i=1;i<=tot;i++){
l[i]=r[i-1]+1,r[i]=std::min(r[i-1]+B,n);
for(int j=l[i];j<=r[i];j++)belong[j]=i;
}
for(int i=1;i<=m;i++){
read(q[i].l),read(q[i].r);
q[i].id=i;
}
std::sort(q+1,q+m+1);
int nl=1,nr=n;
for(int i=1;i<=m;i++){
int x=l[belong[q[i].l]];
if(i==1||belong[q[i].l]!=belong[q[i-1].l]){
while(nl>1)add(--nl);
while(nr<n)add(++nr);
cur=mex;
while(nl<x)del(nl++);
}
while(nr>q[i].r)del(nr--);
tmp=cur;
while(nl<q[i].l)del(nl++);
ans[q[i].id]=cur;
while(nl>x)add(--nl);
cur=tmp;
}
for(int i=1;i<=m;i++)write(ans[i]),putchar('\n');
return 0;
}