区间mex 主席树

题目描述

有一个长度为 nn 的数组 a1,a2,,an
m 次询问,每次询问一个区间内最小没有出现过的自然数。

输入格式

第一行 n,m。

第二行为 n 个数。

从第三行开始,每行一个询问 l,r。

输出格式

一行一个数,表示每个询问的答案。

输入
5 5
2 1 0 2 1
3 3
2 3
2 4
1 2
3 5
输出
1
2
3
0
3

说明/提示

对于 100% 的数据:
1n,m2×105
0ai109
1lrn

思路

区间问题我们考虑主席树,如果维护每个权值出现的次数。但是这个不能提供root[L-1]和root[R]作差得到结果。
我们思考:在一个区间出现的数,我们只统计记录离R最近的的出现的下标。区间维护最小值。那么谁第一个出现的最近坐标<L就可以得到答案。

还有a[i]。a[i]>n+1时,不会造成任何贡献。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

struct Tree{
    int mi[200050*40], tot=0, L[200050*40], R[200050*40];
    void BT(int &i, int l, int r){
        i=++tot;
        mi[i]=L[i]=R[i]=0;
        if(l==r){
            return ;
        }
        BT(L[i], l, l+r>>1); BT(R[i], (l+r>>1)+1, r);
    }
    int up_data(int i, int l, int r, int x, int val){
        int rt=++tot;
        mi[rt]=mi[i], L[rt]=L[i], R[rt]=R[i];
        if(l==r){
            mi[rt]=val;
            return rt;
        }
        if(x<=(l+r>>1)){
            L[rt]=up_data(L[i], l, l+r>>1, x, val);
        }
        else{
            R[rt]=up_data(R[i], (l+r>>1)+1, r, x, val);
        }
        mi[rt]=min(mi[L[rt]], mi[R[rt]]);
        return rt;
    }
    int qurey(int i, int l, int r, int k){
        if(l==r){
            return l;
        }
        if(mi[L[i]]<k) return qurey(L[i], l, l+r>>1, k);
        return qurey(R[i], (l+r>>1)+1, r, k);
    }
}T;

int a[200005], root[200005];
int main(){

    int n, m; scanf("%d%d", &n ,&m);
    T.BT(root[0], 1, n+2);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        a[i]++;//a[i]从0
开始
        a[i]=min(a[i], n+2);//>=n+1取n+1
        
        root[i]=T.up_data(root[i-1], 1, n+2, a[i], i);
    }
    while(m--){
        int x, y; scanf("%d%d", &x, &y);
        printf("%d\n", T.qurey(root[y], 1, n+2, x)-1);
    }

    return 0;
}
posted @   liweihang  阅读(300)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
Live2D
欢迎阅读『区间mex 主席树』
点击右上角即可分享
微信分享提示