Problem - B - Codeforces
維護字首區間mex和字尾區間mex,列舉二者相同的斷點
原理
隨區間增長,\(\texttt{mex}\) 只可能增,不可能減,所以可以用一個變數維護目前的 \(mex\),區間擴大後可以直接沿用較小區間的 \(mex\),再處理增加即可。
維護 \(\texttt{mex}\)
std::set<int> S;//當前集合內的元素
int mex(0);//當前mex
for (int i = l; i < r; i++) {
S.insert(a[i]);
while(S.contains(mex)) {
mex++;
}
}
程式碼
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (auto& x : a) std::cin >> x;
std::set<int> preS, sufS;
std::vector<int> pre(n), suf(n);
int preMex(0), sufMex(0);
for (int i = 0; i < n; i++) {
preS.insert(a[i]);
while(preS.contains(preMex)) {
preMex++;
}
pre[i] = preMex;
}
for (int i = n - 1; i >= 0; i--) {
sufS.insert(a[i]);
while(sufS.contains(sufMex)) {
sufMex++;
}
suf[i] = sufMex;
}
for (int i = 0; i < n; i++) {
if (pre[i] == suf[i + 1]) {
std::cout << 2 << '\n';
std::cout << 1 << ' ' << i + 1 << '\n';
std::cout << i + 1 + 1 << ' ' << n << '\n';
return ;
}
}
error; return ;
}