链接: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;
}