zoukankan      html  css  js  c++  java
  • P4137 Rmq Problem / mex 强制在线做法

    Problem

    给定一个数组(a),每次询问给定一个区间([l,r]),求区间(operatorname{mex})
    (n le 2 imes 10 ^ 5,a_i le 10 ^ 9)

    Solution

    考虑用主席树做。每个节点记录它代表的区间权值在当前最早出现的位置。查询的时候直接在(Root_r)上查询$ < l$的即可。

    # include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 5;
    int n,m;
    int a[N],Root[N],tot = 0;
    struct node
    {
        int mex,l,r;
    }T[N << 5];
    void update(int &root,int pre,int l,int r,int x,int d)
    {
        root = ++tot;
        T[root] = T[pre];
        if(l == r)
        {
            T[root].mex = d;
            return;
        }
        int mid = (l + r) >> 1;
        if(x <= mid) update(T[root].l,T[pre].l,l,mid,x,d);
        if(x > mid) update(T[root].r,T[pre].r,mid + 1,r,x,d);
        T[root].mex = min(T[T[root].l].mex,T[T[root].r].mex);
        return;
    }
    int query(int root,int l,int r,int k)
    {
        if(l == r) return l;
        int mid = (l + r) >> 1;
        if(T[T[root].l].mex < k) return query(T[root].l,l,mid,k);
        else return query(T[root].r,mid + 1,r,k);
    }
    int main(void)
    {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
        for(int i = 1; i <= n; i++)
        {
            if(a[i] >= n) Root[i] = Root[i - 1];
            else update(Root[i],Root[i - 1],1,n + 1,a[i] + 1,i);
        }
        while(m--)
        {
            int l,r; scanf("%d%d",&l,&r);
            printf("%d
    ",query(Root[r],1,n + 1,l) - 1);
        }
        return 0;
    }
    
  • 相关阅读:
    hdoj 1002大数加法
    nuxt踩坑
    vue 打包上线后 css3渐变属性丢失的问题解决方案
    linux下crontab不能运行问题
    [转]谈谈数据库的ACID
    web集群时session共享
    redis缓存队列+MySQL +php任务脚本定时批量入库
    Yii2 加载css、js 载静态资源
    PHP实现四种基本排序算法
    phpstorm快捷键
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/15107272.html
Copyright © 2011-2022 走看看