• 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;
    }
    
  • 相关阅读:
    Revit扩展组件介绍之_AdWindow
    PropertyGrid使用总结5 UITypeEditor
    PropertyGrid使用总结4 IcustomTypeDescriptor
    PropertyGrid使用总结3 Descriptor
    PropertyGrid使用总结2 TypeConverter
    JavaScript之Ajax学习
    JavaScript正则表达式
    JavaScript面向对象学习笔记
    node入门学习1
    JavaScript随笔8
  • 原文地址:https://www.cnblogs.com/luyiming123blog/p/15107272.html
Copyright © 2020-2023  润新知