牛牛的mex(思维-前后缀最小值)

链接:https://ac.nowcoder.com/acm/contest/7079/A
来源:牛客网
 

牛牛的mex

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld

题目描述

牛牛现在有一个长度为 nnn 的序列 a1,a2,…,ana_1,a_2,\ldots,a_na1​,a2​,…,an​。现在牛牛有 qqq 次询问,每次想询问区间 [l,r][l,r][l,r] 的 mex 是什么。

 

一个序列的 mex 定义为最小未出现的自然数。

输入描述:

 

第一行两个整数 n,qn,qn,q 表示序列长度和询问次数。

 

接下来一行 nnn 个非负整数,表示序列 aia_iai​。

 

 

 

接下来 qqq 行,每行两个整数 li,ril_i,r_ili​,ri​ 表示询问的区间。

输出描述:

 

qqq 行,每行表示询问的答案。

示例1

输入

复制5 2 4 3 0 1 2 2 4 1 5

5 2
4 3 0 1 2
2 4
1 5

输出

复制2 5

2
5

备注:

n,q≤105,0≤ai<nn,q \leq 10^5,0 \leq a_i < nn,q≤105,0≤ai​<n 且 aia_iai​ 互不相同

 


刚开始以为是洛谷那道题,后来发现其实题目条件不同,完全可以不用莫队/权值线段树写。不过如果要练习莫队/权值线段是也可以的-----洛谷P4137

这题是个思维题,查询区间内未出现的最小值,应当出现在哪里呢?答案是出现在不被查询的区间里的最小的那个,那前缀取一个最小,后缀取一个最小,O(n)预处理,O(1)查询就好了

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+100;
typedef long long LL;
LL pre[maxn],suf[maxn]; 
LL a[maxn];
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,q;cin>>n>>q;
  pre[0]=suf[n+1]=n;
  for(LL i=1;i<=n;i++) cin>>a[i];
  for(LL i=1;i<=n;i++) pre[i]=min(pre[i-1],a[i]);
  for(LL i=n;i>=1;i--) suf[i]=min(suf[i+1],a[i]);
  while(q--){
  	LL l,r;cin>>l>>r;
  	cout<<min(pre[l-1],suf[r+1])<<endl;
  }
return 0;
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值