题意:
求所有子数组的 M E X MEX MEX组成的序列的 M E X MEX MEX
题解:
首先,如果要使 M E X MEX MEX 为 x x x ,则必须满足:
1. 1. 1. ( 1 , x − 1 ) (1,x-1) (1,x−1) 都出现过
2. 2. 2. x x x 没出现过
那么怎么求出这些 x x x 呢,考虑暴力一点的做法,枚举右端点 i i i ,考虑是否存在区间使得 M E X MEX MEX为 x x x ,那么利用权值线段树维护每个值的最近出现的位置,求出 ( 1 , x − 1 ) (1,x-1) (1,x−1)的最小的位置 p p p,如果最后一次出现 x x x 的位置在 p p p 之前,那么说明可以得到 x x x 。但是这样枚举肯定会 t l e tle tle 。再观察,下一个 x x x 出现的位置肯定在 i i i 之后。那么我们对 x x x 枚举下一个出现的位置,然后考虑上一个出现的位置是否小于 p p p 。通俗的讲,就是枚举数组的每个位置,看上一个 a [ i ] a[i] a[i]出现的位置是否在 p p p 之前即可。
代码:
#pragma GCC diagnostic error "-std=c++11"
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
const int mod = 1e9 + 7;
const int MAXN = 2e5 + 5;
const int inf = 0x3f3f3f3f;
int a[MAXN];
int vis[MAXN], pre[MAXN];
struct node {
int l, r;
int mi;
/* data */
} node[MAXN << 2];
void build(int l, int r, int num)
{
node[num].l = l;
node[num].r = r;
if (l == r) {
node[num].mi = 0;
return;
}
int mid = (l + r) >> 1;
build(l, mid, num << 1);
build(mid + 1, r, num << 1 | 1);
node[num].mi = min(node[num << 1].mi, node[num << 1 | 1].mi);
}
void updata(int pos, int val, int num)
{
if (node[num].l == node[num].r) {
node[num].mi = val;
return;
}
int mid = (node[num].l + node[num].r) >> 1;
if (pos <= mid)
updata(pos, val, num << 1);
else
updata(pos, val, num << 1 | 1);
node[num].mi = min(node[num << 1].mi, node[num << 1 | 1].mi);
}
int query(int l, int r, int num)
{
if (node[num].l >= l && node[num].r <= r) {
return node[num].mi;
}
int mid = (node[num].l + node[num].r) >> 1;
int mi = 1e9;
if (l <= mid)
mi = min(mi, query(l, r, num << 1));
if (r > mid)
mi = min(mi, query(l, r, num << 1 | 1));
return mi;
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
for (int i = 1; i <= n + 2; i++)
pre[i] = 0;
build(1, n + 2, 1);
for (int i = 1; i <= n; i++) {
if (a[i] > 1) {
vis[1] = 1;
int pos = query(1, a[i] - 1, 1);
if (pos>pre[a[i]]){
vis[a[i]] = 1;
}
}
updata(a[i], i, 1);
pre[a[i]] = i;
}
for (int i = 2; i <= n + 2; i++){
if(query(1,i-1,1)>pre[i]){
vis[i] = 1;
}
}
for (int i = 1; i <= n + 2;i++){
if(!vis[i]){
cout << i << endl;
return 0;
}
}
}