Description
Input
Output
Sample Input
7 5
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
0 2 1 0 1 3 2
1 3
2 3
1 4
3 6
2 7
Sample Output
3
0
3
2
4
0
3
2
4
HINT
又是第一眼看出了第一步然后不想去想了。。
我们先暴力弄出以1为开头到位置x的mex[x],可以体会到mex[]是单调的。
然后就可以乱搞了。
对于询问左端点排序,然后当左端点=当前mex左端点的时候直接输出
如果不等于,那么我们记录当前数下一个出现位置next[i]
那么可以把i+1到next[i]-1都更新一遍,因为mex是单调的,所以反过来更新,从next[i]-1到i+1,一旦不能更新就break
这样就可以得出所有的答案了
#include<cstdio>
#include<algorithm>
using namespace std;
int a[200001],v[200001],last[200001],mex[200001],next[200001];
int ans[200001];
int n;
struct getask
{
int l,r;
int t;
}ask[200001];
inline bool cmp1(getask x,getask y)
{
if(x.l<y.l)
return true;
return false;
}
inline bool cmp2(getask x,getask y)
{
if(x.t<y.t)
return true;
return false;
}
inline void change(int x)
{
int i;
int ed=next[x];
if(ed==0)
ed=n+1;
mex[x]=0;
for(i=ed-1;i>x;i--) //这里倒着更新太神。。
{
if(mex[i]>a[x])
mex[i]=a[x];
else
break;
}
}
int main()
{
//freopen("mex.in","r",stdin);
//freopen("mex.out","w",stdout);
int q;
scanf("%d%d",&n,&q);
int i,j;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
int now=0;
for(i=1;i<=n;i++)
{
v[a[i]]=1;
while(v[now]!=0)
now++;
mex[i]=now;
}
for(i=1;i<=n;i++)
{
next[last[a[i]]]=i;
next[i]=n+1;
last[a[i]]=i;
}
for(i=1;i<=q;i++)
{
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].t=i;
}
sort(ask+1,ask+1+q,cmp1);
int la=1;
for(i=1;i<=q;i++)
{
if(ask[i].l==la)
ans[ask[i].t]=mex[ask[i].r];
else
{
for(j=la;j<ask[i].l;j++)
change(j);
ans[ask[i].t]=mex[ask[i].r];
}
la=ask[i].l;
}
for(i=1;i<=q;i++)
printf("%d\n",ans[i]);
return 0;
}