Submission #1352414

#TimeUsernameProblemLanguageResultExecution timeMemory
1352414Alex1298Equalmex (CEOI25_equalmex)C++20
0 / 100
2096 ms311668 KiB
#include <bits/stdc++.h>
using namespace std;

static const int MAXV = 400000;
static const int B = 700;

vector<int> solve(
    int n, vector<int>& v,
    int q, vector<pair<int,int>>& queries
) {
    /* ---------------- POSITIONS ---------------- */
    vector<vector<int>> pos(MAXV + 2);
    for (int i = 0; i < n; i++)
        pos[v[i]].push_back(i);

    /* ---------------- MEX OFFLINE ---------------- */
    vector<int> last(MAXV + 2, -1);
    vector<vector<int>> qs(n);
    for (int i = 0; i < q; i++)
        qs[queries[i].second].push_back(i);

    vector<int> mex(q);
    set<int> missing;
    for (int i = 1; i <= MAXV + 1; i++)
        missing.insert(i);

    for (int i = 0; i < n; i++) {
        int x = v[i];
        if (last[x] == -1)
            missing.erase(x);
        last[x] = i;

        for (int qi : qs[i]) {
            int l = queries[qi].first;
            while (!missing.empty()) {
                int m = *missing.begin();
                if (last[m] >= l) {
                    missing.erase(m);
                } else break;
            }
            mex[qi] = *missing.begin();
        }
    }

    /* ---------------- nextEnd PRECOMPUTE ---------------- */
    vector<vector<int>> nextEnd(B + 1, vector<int>(n, n));

    for (int m = 1; m <= B; m++) {
        vector<int> cnt(m, 0);
        int need = m - 1;
        int have = 0;
        int r = 0;

        for (int l = 0; l < n; l++) {
            while (r < n && have < need) {
                if (v[r] < m) {
                    if (++cnt[v[r]] == 1)
                        have++;
                }
                r++;
            }
            if (have == need)
                nextEnd[m][l] = r - 1;

            if (v[l] < m) {
                if (--cnt[v[l]] == 0)
                    have--;
            }
        }
    }

    /* ---------------- ANSWER QUERIES ---------------- */
    vector<int> ans(q);

    for (int i = 0; i < q; i++) {
        int l = queries[i].first;
        int r = queries[i].second;
        int m = mex[i];

        int cur = l;
        int cnt = 0;

        if (m <= B) {
            while (cur <= r) {
                int e = nextEnd[m][cur];
                if (e > r) break;
                cnt++;
                cur = e + 1;
            }
        } else {
            while (cur <= r) {
                int e = cur;
                for (int x = 1; x < m; x++) {
                    auto it = lower_bound(pos[x].begin(), pos[x].end(), cur);
                    if (it == pos[x].end()) {
                        e = n;
                        break;
                    }
                    e = max(e, *it);
                }
                if (e > r) break;
                cnt++;
                cur = e + 1;
            }
        }
        ans[i] = cnt;
    }

    return ans;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...