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

    【传送门:BZOJ3585


    简要题意:

      给出一个长度为n的数列,有m个询问,每个询问输入l,r,求出l到r之间没出现过的最小自然数


    题解:

      莫队+权值分块

      只要处理每一个权值块总共出现多少种数,每当找到一个权值块出现的种数不等于总共的种数,就直接在这个块里找哪个没出现过就行了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    struct question
    {
        int l,r,id,d;
    }q[210000];
    int belong[210000],L[1100],R[1100],block;
    bool cmp1(question n1,question n2)
    {
        if(belong[n1.l]<belong[n2.l]) return true;
        if(belong[n1.l]>belong[n2.l]) return false;
        if(n1.r<n2.r) return true;
        if(n1.r>n2.r) return false;
        return false;
    }
    bool cmp2(question n1,question n2)
    {
        return n1.id<n2.id;
    }
    int a[210000],d[210000];
    int sum[1100];
    void del(int x)
    {
        d[x]--;
        if(d[x]==0) sum[belong[x]]--;
    }
    void add(int x)
    {
        d[x]++;
        if(d[x]==1) sum[belong[x]]++;
    }
    int solve()
    {
        for(int i=1;i<=block;i++)
        {
            if(sum[i]!=R[i]-L[i]+1)
            {
                for(int j=L[i];j<=R[i];j++)
                {
                    if(d[j]==0) return j;
                }
            }
        }
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        block=int(sqrt(n));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);a[i]++;
            if(a[i]>n) a[i]=n;
            int t=(i-1)/block+1;
            belong[i]=t;
            if(L[t]==0) R[t-1]=i-1,L[t]=i;
        }
        R[belong[n]]=n;
        for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
        sort(q+1,q+m+1,cmp1);
        int l=1,r=0;
        memset(d,0,sizeof(d));
        for(int i=1;i<=m;i++)
        {
            while(l<q[i].l) del(a[l]),l++;
            while(l>q[i].l) l--,add(a[l]);
            while(r<q[i].r) r++,add(a[r]);
            while(r>q[i].r) del(a[r]),r--;
            q[i].d=solve()-1;
        }
        sort(q+1,q+m+1,cmp2);
        for(int i=1;i<=m;i++) printf("%d
    ",q[i].d);
        return 0;
    }

     

  • 相关阅读:
    windows tensorflow gpu pip 安装
    记笔记本windows锁定cpu频率的问题
    关于arcgis闪退或停止运行的解决办法
    机器学习听课 | 线性回归 | 06
    剑指offer | 二叉树中和为某一值的路径 | 30
    剑指offer | 二叉搜索树的后序遍历序列 | 29
    剑指offer | 从上往下打印二叉树 | 28
    机器学习经典案例 | 目录 | 00
    剑指offer | 二叉树的镜像 | 27
    剑指offer | 树的子结构 | 26
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8743770.html
Copyright © 2011-2022 走看看