Written with StackEdit.
有一个长度为\(n\)的数组\({a_1,a_2,...,a_n}\)。\(m\)次询问,每次询问一个区间内最小没有出现过的自然数。
第一行\(n,m\)。
第二行为\(n\)个数。
从第三行开始,每行一个询问\(l,r\)。
一行一个数,表示每个询问的答案。
5 5
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5
1
2
3
0
3
对于\(30\%\)的数据:
\(1<=n,m<=1000.\)
对于\(100\%\)的数据:
\(1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n.\)
#include<bits/stdc++.h>
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>‘9‘||jp<‘0‘)&&jp!=‘-‘)
jp=getchar();
if (jp==‘-‘)
{
fh=-1;
jp=getchar();
}
while (jp>=‘0‘&&jp<=‘9‘)
{
out=out*10+jp-‘0‘;
jp=getchar();
}
return out*fh;
}
const int MAXN=2e5+10;
int cnt[MAXN];
set<int> s;
int Ans[MAXN];
int n,m;
int a[MAXN];
int belong[MAXN],BlockSize;
int L,R,res;
struct Query{
int l,r;
int id;
bool operator < (const Query &rhs) const
{
if(belong[l]!=belong[rhs.l])
return belong[l]<belong[rhs.l];
return belong[r]<belong[rhs.r];
}
}q[MAXN];
void BuildBlocks()
{
BlockSize=sqrt(n);
for(int i=1;i<=n;++i)
belong[i]=(i/BlockSize)+1;
}
void add(int pos)
{
++cnt[a[pos]];
for(int i=res;i<=n+2;++i)
if(cnt[i]==0)
{
res=i;
return;
}
}
void remove(int pos)
{
--cnt[a[pos]];
if(cnt[a[pos]]==0)
res=min(res,a[pos]);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;++i)
a[i]=read(),a[i]=a[i]>n?n+1:a[i];
for(int i=1;i<=m;++i)
{
q[i].id=i;
q[i].l=read();
q[i].r=read();
}
for(int i=0;i<=n;++i)
s.insert(i);
a[0]=n+2;
BuildBlocks();
sort(q+1,q+1+m);
L=0,R=0;
for(int i=1;i<=m;++i)
{
int l=q[i].l,r=q[i].r;
while(L<l)
remove(L),++L;
while(L>l)
--L,add(L);
while(R<r)
++R,add(R);
while(R>r)
remove(R),--R;
Ans[q[i].id]=res;
}
for(int i=1;i<=m;++i)
printf("%d\n",Ans[i]);
return 0;
}
原文:https://www.cnblogs.com/jklover/p/10105545.html