• BZOJ 3585: mex [主席树]


    3585: mex

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 787  Solved: 422
    [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 

    Source

    By 佚名提供


    参考:http://blog.csdn.net/werkeytom_ftd/article/details/50975467

    感觉是非常神的做法

    建立权值线段树,每个位置i保存数字i出现的最右端

    查询[l,r],就是找第r棵前缀线段树中第一个值<l的

    维护区间最小值就可以做到了

     

    //
    //  main.cpp
    //  bzoj3585
    //
    //  Created by Candy on 2017/1/28.
    //  Copyright © 2017年 Candy. All rights reserved.
    //
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define lc(x) t[x].l
    #define rc(x) t[x].r
    const int N=2e5+5,MX=1e8+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,Q,a[N],l,r;
    struct node{
        int l,r,mn;
    }t[N*30];
    int sz,root[N];
    void ins(int &x,int l,int r,int p,int v){//right of p is v
        t[++sz]=t[x];x=sz;
        if(l==r) t[x].mn=v;
        else{
            int mid=(l+r)>>1;
            if(p<=mid) ins(t[x].l,l,mid,p,v);
            else ins(t[x].r,mid+1,r,p,v);
            t[x].mn=min(t[lc(x)].mn,t[rc(x)].mn);
        }
    }
    int query(int x,int l,int r,int v){
        if(l==r) return l;
        else{
            int mid=(l+r)>>1;
            if(t[lc(x)].mn<v) return query(t[x].l,l,mid,v);
            else return query(t[x].r,mid+1,r,v);
        }
    }
    int main(int argc, const char * argv[]) {
        n=read();Q=read();
        for(int i=1;i<=n;i++) a[i]=read(),root[i]=root[i-1],ins(root[i],0,MX,a[i],i);
        while(Q--){
            l=read();r=read();
            printf("%d
    ",query(root[r],0,MX,l));
        }
        return 0;
    }
  • 相关阅读:
    LeetCode 152. 乘积最大子数组 | Python
    LeetCode 31. 下一个排列 | Python
    LeetCode 136. 只出现一次的数字 | Python
    LeetCode 102. 二叉树的层序遍历 | Python
    LeetCode 155. 最小栈 | Python
    LeetCode 69. x 的平方根 | Python
    Python3 高阶函数
    Python3 装饰器
    Python3 递归函数
    Python3 函数
  • 原文地址:https://www.cnblogs.com/candy99/p/6354623.html
Copyright © 2020-2023  润新知