bzoj 3585 mex

Posted jklover

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 3585 mex相关的知识,希望对你有一定的参考价值。

Written with StackEdit.

题目描述

有一个长度为(n)的数组({a_1,a_2,...,a_n})(m)次询问,每次询问一个区间内最小没有出现过的自然数。

Input

第一行(n,m)
第二行为(n)个数。
从第三行开始,每行一个询问(l,r)

Output

一行一个数,表示每个询问的答案。

Sample Input

5 5
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5

Sample Output

1
2
3
0
3

HINT

对于(30\%)的数据:
(1<=n,m<=1000.)

对于(100\%)的数据:
(1<=n,m<=200000,0<=ai<=10^9,1<=l<=r<=n.)

Solution

  • 多个区间询问,可以离线,并且可以(O(1))转移,考虑使用莫队.
  • 但是(a_ileq 10^9),直接开个(cnt)数组记录当前区间内的各种个数似乎不可做?
  • 然而,对于大于(n)的元素,我们可以直接无视它.
  • 一方面,它一定不会成为答案,否则需要出现至少(0)~(n)(n+1)个数.
  • 另一方面,它肯定不会对答案做出贡献.否则答案也会大于(n),据上,不可能.
  • 所以(a_i)的范围只是虚张声势...我们处理时将大于(n)的数都视作(n+1)即可.
  • 然后就是一个愉快的莫队板子题了.
#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
",Ans[i]);
    return 0;
}














以上是关于bzoj 3585 mex的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3585: mex|莫队算法

[BZOJ3585][BZOJ3339]mex

bzoj 3585: mex

bzoj#3585. mex

bzoj3585 mex

BZOJ3585: mex