BZOJ3585: mex

3585: mex

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 322  Solved: 169
[Submit][Status]

Description

  有一个长度为n的数组{a1,a2,...,an}。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

数据规模和约定

  对于100%的数据:

  1<=n,m<=200000

  0<=ai<=109

  1<=l<=r<=n

  对于30%的数据:

  1<=n,m<=1000

题解:

同上一题。

只不过a[i]是int范围内的,那我们只要把v数组换成map即可。

代码:

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<algorithm>
  6 #include<iostream>
  7 #include<vector>
  8 #include<map>
  9 #include<set>
 10 #include<queue>
 11 #include<string>
 12 #define inf 1000000000
 13 #define maxn 250000+5
 14 #define maxm 500+100
 15 #define eps 1e-10
 16 #define ll long long
 17 #define pa pair<int,int>
 18 #define for0(i,n) for(int i=0;i<=(n);i++)
 19 #define for1(i,n) for(int i=1;i<=(n);i++)
 20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 22 #define mod 1000000007
 23 using namespace std;
 24 inline int read()
 25 {
 26     int x=0,f=1;char ch=getchar();
 27     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 28     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 29     return x*f;
 30 }
 31 int n,m,a[maxn],sg[maxn],next[maxn],ans[maxn];
 32 map<int,int>mp;
 33 struct seg{int l,r,mi;}t[4*maxn];
 34 struct rec{int l,r,id;}c[maxn];
 35 inline void build(int k,int l,int r)
 36 {
 37     t[k].l=l;t[k].r=r;int mid=(l+r)>>1;
 38     t[k].mi=inf;
 39     if(l==r){t[k].mi=sg[l];return;}
 40     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
 41 }
 42 inline void update(int k,int z)
 43 {
 44     t[k].mi=min(t[k].mi,z);
 45 }
 46 inline void pushdown(int k)
 47 {
 48     if(t[k].mi==inf)return;
 49     update(k<<1,t[k].mi);
 50     update(k<<1|1,t[k].mi);
 51     t[k].mi=inf;
 52 }
 53 inline void change(int k,int x,int y,int z)
 54 {
 55     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
 56     if(l==x&&r==y){update(k,z);return;}
 57     pushdown(k);
 58     if(y<=mid)change(k<<1,x,y,z);
 59     else if(x>mid)change(k<<1|1,x,y,z);
 60     else change(k<<1,x,mid,z),change(k<<1|1,mid+1,y,z);
 61 }
 62 inline int query(int k,int x)
 63 {
 64     int l=t[k].l,r=t[k].r,mid=(l+r)>>1;
 65     if(l==r)return t[k].mi;
 66     pushdown(k);
 67     if(x<=mid)return query(k<<1,x);else return query(k<<1|1,x);
 68 }
 69 inline bool cmp(rec x,rec y){return x.l<y.l;}
 70 int main()
 71 {
 72     freopen("input.txt","r",stdin);
 73     freopen("output.txt","w",stdout);
 74     n=read();m=read();int k=0;
 75     for1(i,n)
 76     {
 77         a[i]=read();
 78         mp[a[i]]=1;
 79         if(a[i]==k){while(mp[k])k++;}
 80         sg[i]=k;
 81     }
 82     mp.clear();
 83     build(1,1,n);
 84     for1(i,m)c[i].l=read(),c[i].r=read(),c[i].id=i;
 85     sort(c+1,c+m+1,cmp);
 86     for3(i,n,1)next[i]=mp[a[i]],mp[a[i]]=i;
 87     int now=1;
 88     for1(i,m)
 89     {
 90         while(now<c[i].l)
 91         {
 92             if(!next[now])next[now]=n+1;
 93             if(next[now]-1>=now+1)change(1,now+1,next[now]-1,a[now]);
 94             now++;
 95         }
 96         ans[c[i].id]=query(1,c[i].r);
 97     }
 98     for1(i,m)printf("%d
",ans[i]);
 99     return 0;
100 }
View Code
原文地址:https://www.cnblogs.com/zyfzyf/p/4149220.html