結果

問題 No.1526 Sum of Mex 2
ユーザー t33ft33f
提出日時 2021-06-02 23:36:29
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 47 ms / 3,000 ms
コード長 4,157 bytes
コンパイル時間 949 ms
コンパイル使用メモリ 95,308 KB
実行使用メモリ 11,408 KB
最終ジャッジ日時 2024-11-15 19:22:25
合計ジャッジ時間 4,138 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 2 ms
5,248 KB
testcase_02 AC 2 ms
5,248 KB
testcase_03 AC 2 ms
5,248 KB
testcase_04 AC 2 ms
5,248 KB
testcase_05 AC 2 ms
5,248 KB
testcase_06 AC 2 ms
5,248 KB
testcase_07 AC 2 ms
5,248 KB
testcase_08 AC 2 ms
5,248 KB
testcase_09 AC 2 ms
5,248 KB
testcase_10 AC 2 ms
5,248 KB
testcase_11 AC 2 ms
5,248 KB
testcase_12 AC 2 ms
5,248 KB
testcase_13 AC 7 ms
5,248 KB
testcase_14 AC 7 ms
5,248 KB
testcase_15 AC 9 ms
5,248 KB
testcase_16 AC 38 ms
7,680 KB
testcase_17 AC 28 ms
6,512 KB
testcase_18 AC 5 ms
5,248 KB
testcase_19 AC 4 ms
5,248 KB
testcase_20 AC 18 ms
5,376 KB
testcase_21 AC 38 ms
7,424 KB
testcase_22 AC 23 ms
6,016 KB
testcase_23 AC 39 ms
7,680 KB
testcase_24 AC 41 ms
7,808 KB
testcase_25 AC 37 ms
7,552 KB
testcase_26 AC 40 ms
7,808 KB
testcase_27 AC 41 ms
7,936 KB
testcase_28 AC 42 ms
7,856 KB
testcase_29 AC 40 ms
7,808 KB
testcase_30 AC 41 ms
8,064 KB
testcase_31 AC 42 ms
8,024 KB
testcase_32 AC 40 ms
7,680 KB
testcase_33 AC 47 ms
11,408 KB
evil_largest AC 146 ms
27,788 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cassert>
#include <map>
#include <tuple>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

long long bruteforce(const vector<int>& a) {
    const int n = a.size();
    long long ans = 0;
    for (int l = 0; l < n; l++) {
        for (int r = l; r < n; r++) {
            vector<bool> b(n+2, false);
            for (int i = l; i <= r; i++) b[a[i]] = true;
            for (int i = 1; i <= n+1; i++)
                if (!b[i]) { ans += i; break; }
        }
    }
    return ans;
}


long long solve(const vector<int>& a) {
    const int n = a.size();
    vector<int> b[n+1];
    for (int i = 0; i < n; i++) b[a[i]].push_back(i);
    long long ans = (long long)n * (n + 1) / 2;
    if (b[1].empty()) {
        return ans;
    }

    struct entry {
        int l, r;
        long long c;
        bool operator<(const entry& rhs) const {
            return l < rhs.l || (l == rhs.l && r < rhs.r);
        };
    };

    set<entry> v;
    long long s = 0;
    for (int i : b[1]) {
        const int l = v.empty() ? -1 : v.rbegin()->l;
        const long long c = (long long)(i - l) * (n - i);
        v.insert({i, i, c});
        s += c;
    }
    ans += s;
    for (int x = 2; x <= n; x++) {
        // cerr << "x = " << x << endl;
        // for (auto [i, j, k] : v)
        //     cerr << '(' << i << ' ' << j << ' ' << k << "); "; cerr << endl;
        // cerr << "ans = " << ans << endl;
        // cerr << "s = " << s << endl;
        if (b[x].empty()) break;
        // first
        {
            const int k = b[x][0];
            const auto left = v.begin();
            auto right = v.begin();
            while (right != v.end() && right->r < k) right++;
            if (left != right) {
                entry e2 = *prev(right);
                for (auto it = v.begin(); it != right; ) {
                    s -= it->c;
                    it = v.erase(it);
                }
                long long c = (long long)(e2.l + 1) * (n - k);
                e2.r = k;
                e2.c = c;
                s += c;
                v.insert(e2);
            }
        }
        // middle
        for (int j = 1; j < b[x].size(); j++) {
            const int kl = b[x][j-1], kr = b[x][j];
            const auto left = v.lower_bound({kl, kl, 0});
            auto right = left;
            while (right != v.end() && right->r < kr) right++;
            if (left != right) {
                entry e1 = *left;
                entry e2 = *prev(right);
                const int l1 = left == v.begin() ? -1 : prev(left)->l;
                const int l2 = kl; // prev(right) == v.begin() ? kl : prev(right, 2)->l;
                // cerr << "l2 = " << l2 << endl;
                e1.l = kl;
                e1.c = (long long)(kl - l1) * (n - e1.r);
                e2.r = kr;
                e2.c = (long long)(e2.l - l2) * (n - kr);
                for (auto it = left; it != right; ) {
                    s -= it->c;
                    it = v.erase(it);
                }
                s += e1.c + e2.c;
                v.insert(e1);
                v.insert(e2);
            }
        }
        // last
        {
            const int kl = b[x].back();
            const auto left = v.lower_bound({kl, kl, 0});
            if (left != v.end()) {
                entry e1 = *left;
                const int l1 = left == v.begin() ? -1 : prev(left)->l;
                e1.l = kl;
                e1.c = (long long)(kl - l1) * (n - e1.r);
                for (auto it = left; it != v.end(); ) {
                    s -= it->c;
                    it = v.erase(it);
                }
                s += e1.c;
                v.insert(e1);
            }
        }
        ans += s;
    }
    return ans;
}

int main() {
    int n; cin >> n;
    vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i];
    long long ans = solve(a);
    // long long expect = bruteforce(a);
    // if (expect != ans) {
    //     cerr << "wrong answer " << ans << ' ' << expect << endl;
    //     cerr << n << endl;
    //     for (int x : a) cerr << x << ' '; cerr << endl;
    // }
    cout << ans << endl;
}
0