从CF1935B学习维护前后缀区间mex

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 ;
}
posted @ 2024-03-10 14:02  加固文明幻景  阅读(27)  评论(0编辑  收藏  举报