zoukankan      html  css  js  c++  java
  • mex

    mex


    题目描述

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

    输入输出格式

    输入格式:

    第一行n,m。

    第二行为n个数。

    从第三行开始,每行一个询问l,r。

    输出格式:

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

    题目分析:

    首先可以发现这个题可以根号算法暴力搞。。。

    然后觉得不是很好做。

    考虑如果我们只记录每个数最后出现的时候是什么。那么我们在查询的时候直接查询(R)这个时刻第一个出现的最后时刻比(L)小的就可以了。

    但是值域较大,不能直接硬上。

    可以进行离散化,但是处理比较麻烦。需要先将所有的(a[i])(a[i]+1)都放进离散化的数组里面。同时也需要将(0)放入数组。然后进行离散化,之后直接上主席树就可以了。

    有一种比较容易的方法就是考虑到如果给出的值大于(n)的话,那么它就和没有贡献差不多,所以可以直接无视掉,只计算小于等于(n)(a[i])的贡献。这样数组就正常的开就可以了。

    另提一下,这个题没有要求强制在线,所以可以对所有询问之后排序线段树搞。

    #include <bits/stdc++.h>
    using namespace std;
    #define mid (l+r>>1)
    #define ll long long
    # include<algorithm>
    const int MAXN=4e5+7;
    int a[MAXN],L[MAXN<<5],R[MAXN<<5],st[MAXN<<5],T[MAXN],b[MAXN<<2];
    int n,q,size,m;
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int update(int pre,int l,int r,int p,int x)
    {
        int rt=++size;
        L[rt]=L[pre],R[rt]=R[pre];
        if(l==r){
            st[rt]=x;
            return rt;
        }
        if(p<=mid) L[rt]=update(L[pre],l,mid,p,x);
        else R[rt]=update(R[pre],mid+1,r,p,x);
        st[rt]=min(st[L[rt]],st[R[rt]]);
        return rt;
    }
    int query(int v,int l,int r,int x)
    {
        if(!v||l==r) return b[l];
        if(st[L[v]]<x) return query(L[v],l,mid,x);
        else return query(R[v],mid+1,r,x);
    }
    int main()
    {
        b[++m]=0;
        n=read();q=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
            b[++m]=a[i];b[++m]=a[i]+1;
        }
        sort(b+1,b+m+1);
        m=unique(b+1,b+m+1)-b-1;
        T[0]=++size;
        for(int i=1;i<=n;i++){
            int t=lower_bound(b+1,b+m+1,a[i])-b;
            T[i]=update(T[i-1],1,m,t,i);
        }
        
        while(q--){
            int l=read(),r=read();
            printf("%d
    ",query(T[r],1,m,l));
        }
        return 0;
    }
    
  • 相关阅读:
    HTML5全屏API在FireFox/Chrome中的显示差异(转)
    过程需要参数 '@statement' 为 'ntext/nchar/nvarchar'
    程序员面试zhongdian
    select into #T from ,insert into #T select ,insert into #T exec
    Log4Net Layout使用以及扩展
    jdbc报java.lang.ClassNotFoundException: com.mysql.jdbc.Drive
    eclipse的maven项目中找不到Maven Dependencies
    elfinder中通过DirectoryStream.Filter实现筛选隐藏目录(二)
    一个好用的字符过滤,差异匹配补丁的扩展库,各语言版本
    java调用c/c++代码简单实现以及遇见的坑
  • 原文地址:https://www.cnblogs.com/victorique/p/10097257.html
Copyright © 2011-2022 走看看