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
  • 相关阅读:
    建设全功能团队
    gwt之mvc4g
    SQLServer代码差异备份
    DateTimePicker选择到秒
    SQL定时备份并删除过期备份
    Div文本垂直居中
    WinForm当前窗口抓图
    web架构设计经验分享(转)
    用yui compressor 压缩 javascirpt脚本
    查看sqlserver连接数
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9537818.html
Copyright © 2011-2022 走看看