1 条题解

  • 0
    @ 2026-11-2 15:26:14

    糖果(Candy) 题解

    思路分析

    按题目要求使用对应数据结构与算法模拟/递推求解,注意数据范围边界与时间复杂度。

    参考代码

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    struct SegTree {
        int n;
        vector<long long> sum;
        vector<int> mx, lz;
        SegTree(int n) : n(n), sum(4 * n + 5, 0), mx(4 * n + 5, 0), lz(4 * n + 5, -1) {}
    
        void apply(int u, int l, int r, int v) {
            sum[u] = 1LL * (r - l + 1) * v;
            mx[u] = v;
            lz[u] = v;
        }
        void push(int u, int l, int r) {
            if (lz[u] != -1) {
                int mid = (l + r) / 2;
                apply(u * 2, l, mid, lz[u]);
                apply(u * 2 + 1, mid + 1, r, lz[u]);
                lz[u] = -1;
            }
        }
        void pull(int u) {
            sum[u] = sum[u * 2] + sum[u * 2 + 1];
            mx[u] = max(mx[u * 2], mx[u * 2 + 1]);
        }
        void build(int u, int l, int r, const vector<int>& init) {
            if (l == r) {
                sum[u] = mx[u] = init[l];
                return;
            }
            int mid = (l + r) / 2;
            build(u * 2, l, mid, init);
            build(u * 2 + 1, mid + 1, r, init);
            pull(u);
        }
        int find_first_gt(int u, int l, int r, int x) {
            if (mx[u] <= x) return n + 1;
            if (l == r) return l;
            push(u, l, r);
            int mid = (l + r) / 2;
            if (mx[u * 2] > x) return find_first_gt(u * 2, l, mid, x);
            return find_first_gt(u * 2 + 1, mid + 1, r, x);
        }
        void assign(int u, int l, int r, int ql, int qr, int v) {
            if (ql <= l && r <= qr) {
                apply(u, l, r, v);
                return;
            }
            push(u, l, r);
            int mid = (l + r) / 2;
            if (ql <= mid) assign(u * 2, l, mid, ql, qr, v);
            if (qr > mid) assign(u * 2 + 1, mid + 1, r, ql, qr, v);
            pull(u);
        }
    };
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int n;
        if (!(cin >> n)) return 0;
        vector<int> a(n + 1);
        for (int i = 1; i <= n; ++i) cin >> a[i];
        vector<int> cnt(n + 2, 0), init(n + 1, 0);
        int curMex = 0;
        for (int i = 1; i <= n; ++i) {
            if (a[i] <= n + 1) cnt[a[i]]++;
            while (cnt[curMex] > 0) ++curMex;
            init[i] = curMex;
        }
        vector<int> last(n + 2, n + 1), nxt(n + 1, n + 1);
        for (int i = n; i >= 1; --i) {
            if (a[i] <= n + 1) {
                nxt[i] = last[a[i]];
                last[a[i]] = i;
            }
        }
        SegTree st(n);
        st.build(1, 1, n, init);
        long long ans = 0;
        for (int l = 1; l <= n; ++l) {
            ans += st.sum[1];
            st.assign(1, 1, n, l, l, 0);
            int x = a[l];
            if (x <= n) {
                int pos = max(l + 1, st.find_first_gt(1, 1, n, x));
                int r = nxt[l] - 1;
                if (pos <= r) {
                    st.assign(1, 1, n, pos, r, x);
                }
            }
        }
        cout << ans << "\n";
        return 0;
    }
    
    • 1

    信息

    ID
    8803
    时间
    1000ms
    内存
    512MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者