• [BZOJ 3585] mex


    [题目链接]

              https://www.lydsy.com/JudgeOnline/problem.php?id=3585

    [算法]

             两种做法 :

             1. 莫队 , 时间复杂度 : O(Nsqrt(N)) (sqrt表示开根号)

             2. 可持久化线段树 , 我们只需在第i棵线段树上维护每个数最晚出现的时间 , 查询时在线段树上二分即可 , 时间复杂度 :O(NlogN)

    [代码]

            莫队 :

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 200010
    const int inf = 2e9;
    
    struct query
    {
            int l , r;
            int id;
    } q[MAXN];
    
    int n , m , mn = 0;
    int a[MAXN] , cnt[MAXN] , ans[MAXN] , belong[MAXN];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline bool cmp(query a , query b)
    {
            return belong[a.l] == belong[b.l] ? a.r < b.r : a.l < b.l;        
    }
    inline void add(int idx)
    {
            if (a[idx] >= MAXN) return;
            ++cnt[a[idx]];
            while (cnt[mn] > 0)    ++mn;    
    }
    inline void dec(int idx)
    {
            if (a[idx] >= MAXN) return;
            --cnt[a[idx]];
            if (!cnt[a[idx]]) chkmin(mn , a[idx]);
    }
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i <= n; i++) read(a[i]);
            for (int i = 1; i <= m; i++)
            {
                    read(q[i].l);
                    read(q[i].r);        
                    q[i].id = i;
            }
            int block = sqrt(n);
            for (int i = 1; i <= n; i++) belong[i] = (i - 1) / block + 1;
            sort(q + 1 , q + m + 1 , cmp);
            int l = q[1].l , r = q[1].l - 1;
            for (int i = 1; i <= m; i++)
            {
                    while (r < q[i].r)
            {
                add(r + 1);
                r++;
            }
            while (r > q[i].r)
            {
                dec(r);
                r--;
            }
            while (l < q[i].l)
            {
                dec(l);
                l++;
            }
            while (l > q[i].l)
            {
                add(l - 1);
                l--;
            }
                    ans[q[i].id] = mn;
            }
            for (int i = 1; i <= m; i++) printf("%d
    " , ans[i]);
            
            return 0;
        
    }

                   可持久化线段树 :

                    

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200010
    const int inf = 2e9;
    
    int n , m , idx;
    int v[N * 40] , lson[N * 40] , rson[N * 40] , root[N] , a[N];
    
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void build(int &k , int l , int r)
    {
            k = ++idx;
            v[k] = -inf;
            if (l == r) return;
            int mid = (l + r) >> 1;
            build(lson[k] , l , mid);
            build(rson[k] , mid + 1 , r);
    }
    inline void modify(int &k , int old , int l , int r , int pos , int val)
    {
            k = ++idx;
            lson[k] = lson[old] , rson[k] = rson[old];
            v[k] = v[old];
            if (l == r)
            {
                    v[k] = val;
                    return;
            }        
            int mid = (l + r) >> 1;
            if (mid >= pos) modify(lson[k] , lson[k] , l , mid , pos , val);
            else modify(rson[k] , rson[k] , mid + 1 , r , pos , val);
            v[k] = min(v[lson[k]] , v[rson[k]]);
    }
    inline int query(int k , int l , int r , int t)
    {
            if (l == r) return l;
            int mid = (l + r) >> 1;
            if (v[lson[k]] < t) return query(lson[k] , l , mid , t);
            else return query(rson[k] , mid + 1 , r , t);        
    }
    
    int main()
    {
            
            read(n); read(m);
            for (int i = 1; i <= n; i++) read(a[i]);
            build(root[0] , 0 , N - 1);
            for (int i = 1; i <= n; i++)
            {
                    if (a[i] < N)
                       modify(root[i] , root[i - 1] , 0 , N - 1 , a[i] , i);
                    else root[i] = root[i - 1];
            }
            for (int i = 1; i <= m; i++)
            {
                    int l , r;
                    read(l); read(r);
                    printf("%d
    " , query(root[r] , 0 , N - 1 , l));        
            }
            
            return 0;
        
    }
  • 相关阅读:
    bootstrutp module 显示隐藏 模态框
    手机app传统邀请码安装与免邀请码安装区别,如何选择呢?
    好用的一些开源系统
    一个搞笑的招聘启事
    java和android及IOS对接RSA加密经验
    mysql大数据表改表结构方案
    android开发中监控android软件网络请求的软件Charles使用入门
    android IOC框架学习记录
    java分布式事务
    十八届三中全会的综合改革方案将涉及哪些内容?(转自知乎)
  • 原文地址:https://www.cnblogs.com/evenbao/p/9975497.html
Copyright © 2020-2023  润新知