https://codeforces.com/problemset/problem/1436/E
这个题是个线段树
问你子串的mex 的mex
如果子串 的mex没有4,则没有办法分割出 存在1 存在2 存在3 不存在4 的字串出来,所以可以枚举,当前数字是list[i],记录之前list[i]出现位置为pos
利用权值线段树查询1 -- list[i]-1的最小下标是不是大于pos就可以判断了。
#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 2e5+11;
int tree[maxn*4];
int n;
int update(int node,int be,int en,int i,int val) {
int mid = be + en >>1;
int l = node*2;
int r = node*2+1;
if(be == en) {
tree[node] = val;
return 0;
}
if(i <= mid) update(l,be,mid,i,val);
else update(r,mid+1,en,i,val);
tree[node] = min(tree[l] ,tree[r]);
return 0;
}
int ask(int node,int be,int en,int LL,int RR) {
int mid = be + en >>1;
int l = node*2;
int r = node*2+1;
if(LL <= be && en <= RR) {
return tree[node];
}
int val1 =1e9,val2 = 1e9;
if(LL <= mid) val1 = ask(l,be,mid,LL,RR);
if(RR > mid) val2 = ask(r,mid+1,en,LL,RR);
return min(val1,val2);
}
int vis[maxn];
int ans[maxn];
int list[maxn];
int main() {
int len;
cin>>n;
for(int i=1; i<=n; i++) {
update(1,1,n,i,-1);
cin>>list[i];
if(list[i] != 1) ans[1] = 1;
}
//ans表示可以
for(int i=1;i<=n;i++){
if(list[i] == 1){
vis[list[i]] = i;
update(1,1,n,1,i);
}
else{
int mid = ask(1,1,n,1,list[i]-1);
if(mid > vis[list[i]]){
ans[list[i]] |= 1;
}
vis[list[i]] = i;
update(1,1,n,list[i],i);
}
}
for(int i=2;i<=n+1;i++){
int mid = ask(1,1,n,1,i-1);
if(mid > vis[i]){
ans[i] |= 1;
}
}
for(int i=1;i<=n+3;i++){
if(ans[i] == 0){
cout<<i<<endl;
break;
}
}
return 0;
}