zoukankan      html  css  js  c++  java
  • BZOJ3585: mex

    题解: 权值分块 莫队查询即可

    /**************************************************************
        Problem: 3585
        User: c20161007
        Language: C++
        Result: Accepted
        Time:6248 ms
        Memory:8340 kb
    ****************************************************************/
     
    #include <bits/stdc++.h>
    #define N 200005
    #define INF 100000007
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    int n,m,size,size1;
    int p[N],a[N],c[N];
    int vis[N],pp[N];int b[1005];
    typedef struct node{
        int l,r,biao;
        friend bool operator <(node aa,node bb){
            if(p[aa.l]==p[bb.l]) return aa.r<bb.r;
            return p[aa.l]<p[bb.l];
        } 
    }node;
    node d[N];
    int ans[N];
    int main(){
        ios::sync_with_stdio(false);
        n=read();m=read();size=(int)sqrt(n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);p[i]=(i-1)/size+1;
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&d[i].l,&d[i].r);d[i].biao=i;
        }
        sort(d+1,d+m+1);size1=(int)sqrt(n+1);
        for(int i=1;i<=n+1;i++){
            pp[i]=(i-1)/size1+1;
        }
        for(int i=1;i<=pp[n+1];i++) b[i]=min(n+1,size1*i)-(size1*(i-1)+1)+1;
        int L=1;int R=0;
        for(int i=1;i<=m;i++){
            while(R>d[i].r){
                if(a[R]<=n){
                    c[a[R]]--;
                    if(c[a[R]]==0) b[pp[a[R]+1]]++;
                }
                R--;
            }
            while(R<d[i].r){
                R++;
                if(a[R]<=n){
                    c[a[R]]++;
                    if(c[a[R]]==1) b[pp[a[R]+1]]--;
                }
            }
            while(L<d[i].l){
                if(a[L]<=n){
                    c[a[L]]--;
                    if(c[a[L]]==0) b[pp[a[L]+1]]++;
                }
                L++;
            }
            while(L>d[i].l){
                L--;
                if(a[L]<=n){
                    c[a[L]]++;
                    if(c[a[L]]==1) b[pp[a[L]+1]]--;
                }
            }
            for(int j=1;j<=pp[n+1];j++){
                if(b[j]==0) continue;
                else{
                    for(int k=size1*(j-1)+1;k<=min(n+1,size1*j);k++){
                        if(c[k-1]==0){
                            ans[d[i].biao]=k-1;
                            break;
                        }
                    }
                    break;
                }
            }
        }
        for(int i=1;i<=m;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    

    3585: mex

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1611  Solved: 809
    [Submit][Status][Discuss]

    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

  • 相关阅读:
    第十二周助教总结
    第十一周助教总结
    记一次数据库mysql与tidb查询时的区别
    括号校验-Java
    (四)栈和队列的应用
    (三)栈和队列的链式存储结构
    (二)栈和队列的顺序存储结构
    windows开放服务可以远程和被访问(两台电脑可以互相访问)
    (一)栈和队列的基本概念
    (一)数据结构基本概念、存储结构、复杂度
  • 原文地址:https://www.cnblogs.com/wang9897/p/9502661.html
Copyright © 2011-2022 走看看