主席树求Mex:P4137

2023大厂真题提交网址(含题解):

www.CodeFun2000.com(http://101.43.147.120/)

最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练习,体会真题难度。现在OJ已录入50+道2023年最新大厂真题,同时在不断的更新。同时,可以关注"塔子哥学算法"公众号获得每道题的题解。
在这里插入图片描述

主席树求区间没有出现过的最小值
思路:

对于每个数,维护它最后出现的位置。然后维护区间最小值。

查询区间 [ L , R ] [L,R] [L,R]的时候,找到第 R R R颗树.贪心的往左子树走:若左子树的区间最小值 < < < L,就往左走,否则就往右走(右边一定有答案).

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define mid ((l + r) >> 1)
const int maxn = 2e5 + 5;
const int inf = 1e9;
int a[maxn];
int mi[maxn << 5] , ls[maxn << 5] , rs[maxn << 5] , rt[maxn] , tot;
int add (int l , int r , int t , int p , int c)
{
    int now = ++tot;
    ls[now] = ls[t];
    rs[now] = rs[t];
    if (l == r) {
        mi[now] = c;
        return now;
    }
    if (p <= mid) ls[now] = add (l , mid , ls[now] , p , c);
    else rs[now] = add (mid + 1 , r , rs[now] , p , c);
    mi[now] = min (mi[ls[now]] , mi[rs[now]]);
    return now;
}
int ask (int t , int l , int r , int L)
{
    if (l == r) return l;
    if (mi[ls[t]] < L) return ask(ls[t] , l , mid , L);
    return ask(rs[t] , mid + 1 , r , L);
}
int last[maxn];
int main()
{
    int n , m;scanf("%d%d" , &n , &m);
    int up = n + 1;
  //  build(0 , up , rt[0]);
    rt[0] = 0;
    for (int i = 1 ; i <= n ; i++){
        scanf("%d" , a + i);
        if ( a[i] > n ) a[i] = n + 1;
        rt[i] = add(0 , up , rt[i - 1] , a[i] , i);
    }
    while(m--){
        int l , r;scanf("%d%d" , &l , &r);
        printf("%d\n" , ask(rt[r] , 0 , up , l));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值