zoukankan      html  css  js  c++  java
  • Rmq Problem mex

    求区间mex。莫队可做。

    但如果强制在线,就可以用主席树做。

    建立权值线段树,找每个数最后一次出现的位置。查询的时候找第r棵线段树最近出现位置在l之前的最小数即可。update的时候可以update这个数和这个数+1,如果没有这个数+1,那ans就是这个数+1.(好乱啊,看代码吧

    // luogu-judger-enable-o2
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int n,m;
    const int N=4e5+7;
    int rt[N],ls[N<<5],rs[N<<5],last[N<<5],tot,lsh[N],LSH=1,a[N];
    #define mid (l+r>>1)
    void build(int &k,int l,int r) {k=++tot;if(l<r) build(ls[k],l,mid),build(rs[k],mid+1,r);}
    void update(int &k,int pre,int l,int r,int pos,int lst) {
        ls[k=++tot]=ls[pre],rs[k]=rs[pre];last[k]=last[pre];
        if(l==r) {last[k]=lst;return;}
        if(pos<=mid) update(ls[k],ls[pre],l,mid,pos,lst);
        else update(rs[k],rs[pre],mid+1,r,pos,lst);
        last[k]=min(last[ls[k]],last[rs[k]]);
    }
    int query(int k,int l,int r,int c) {
        if(!k||l==r) return lsh[l];
        if(last[ls[k]]>=c) return query(rs[k],mid+1,r,c);
        return query(ls[k],l,mid,c);
    }
    #undef mid
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]),lsh[++LSH]=a[i],lsh[++LSH]=a[i]+1;
        sort(lsh+1,lsh+1+LSH);LSH=unique(lsh+1,lsh+1+LSH)-lsh-1;
        build(rt[0],1,LSH);
        for(int i=1;i<=n;i++) a[i]=lower_bound(lsh+1,lsh+1+LSH,a[i])-lsh,update(rt[i],rt[i-1],1,LSH,a[i],i);
        for(int i=1,l,r;i<=m;i++) {
            scanf("%d%d",&l,&r);
            printf("%d
    ",query(rt[r],1,LSH,l));
        }
        return 0;
    }
    
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    Android百度地图
    Android开发性能优化大总结
    解析Android开发优化之:从代码角度进行优化的技巧
    073 HBASE的读写以及client API
    072 HBase的架构以及各个模块的功能
    071 HBase的安装部署以及简单使用
    070 关于HBase的概述
    069 Hue协作框架
    068 Oozie任务调度框架
    集合的知识点梳理(List,Set,不包含泛型)
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9537818.html
Copyright © 2011-2022 走看看