正题
评测记录:https://www.luogu.org/recordnew/lists?uid=52918&pid=P4137
题目大意
求区间mex。
解题思路
开始发现
a
i
a_i
ai很大,开不了桶。但是转念一想,如果
a
n
s
>
n
+
1
ans>n+1
ans>n+1仅当前n+1个都有,可是最多只有n个,所以
>
n
>n
>n的都没用。
之后开个桶+莫队分块优化就行了。
code
#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 200010
using namespace std;
struct node{
int l,r,id,pos;
}a[N];
int n,m,w[N],l,r,now,id[N],t;
int cnt[N],ans[N];
bool cmp(node x,node y){
return x.pos<y.pos||(x.pos==y.pos&&x.r<y.r);
}
void add(int x)
{
if(w[x]>n) return;
cnt[w[x]]++;
while(cnt[now])
now++;
}
void del(int x)
{
if(w[x]>n) return;
cnt[w[x]]--;
if(!cnt[w[x]])
now=min(now,w[x]);
}
int main()
{
scanf("%d%d",&n,&m);
t=sqrt(n);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
for(int i=1;i<=m;i++)
scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i,a[i].pos=(a[i].l-1)/t+1;
sort(a+1,a+1+m,cmp);
l=1,r=0;
for(int i=1;i<=m;i++)
{
while(l>a[i].l) add(--l);
while(r<a[i].r) add(++r);
while(l<a[i].l) del(l++);
while(r>a[i].r) del(r--);
ans[a[i].id]=now;
//for(int j=0;j<=5;j++)
// printf("%d ",cnt[j]);
//printf(":%d-%d\n",a[i].l,a[i].r);
}
for(int i=1;i<=m;i++)
printf("%d\n",ans[i]);
}