题目大意:给定一个长度为n的数组,m次询问某个区间内的mex值
怒写莫队233
将权值分成√n块,记录每个权值的出现次数以及每块内有多少权值出现过
修改O(1)即可完成 查询时首先扫一遍找到第一个块内有没有覆盖的点的块 然后在块内暴力查找 时间复杂度O(√n)
套个莫队 总时间复杂度O(m√n)
#include
#include
#include
#include
#include
#define M 200200
using namespace std;
struct abcd{
int l,r,id;
bool operator < (const abcd &x) const;
}queries[M];
int n,m,b;
int a[M],belong[M],l[M],r[M];
int L=1,R=0,f[M],block_ans[M],ans[M];
bool abcd :: operator < (const abcd &x) const
{
if(belong[l]!=belong[x.l])
return ln) return ;
if(!f[x]++)
block_ans[belong[x]]++;
}
void Downdate(int x)
{
if(x>n) return ;
if(!--f[x])
block_ans[belong[x]]--;
}
int Query()
{
int i;
if(!f[0]) return 0;
for(i=1;l[i];i++)
if(block_ans[i]!=r[i]-l[i]+1)
break;
int temp=i;
for(i=l[temp];i<=r[temp];i++)
if(!f[i])
return i;
return n;
}
int main()
{
int i;
cin>>n>>m;
b=int(sqrt(n)+1e-7);
for(i=1;i<=n;i++)
belong[i]=(i-1)/b+1;
for(i=1;(i-1)*b+1<=n;i++)
l[i]=(i-1)*b+1,r[i]=min(i*b,n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
for(i=1;i<=m;i++)
scanf("%d%d",&queries[i].l,&queries[i].r),queries[i].id=i;
sort(queries+1,queries+n+1);
for(i=1;i<=m;i++)
{
while(Rqueries[i].l)
Update(a[--L]);
while(R>queries[i].r)
Downdate(a[R--]);
while(L