QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#338985#7605. Yet Another Mex ProblemjrjyyWA 1ms3952kbC++146.0kb2024-02-26 16:02:532024-02-26 16:02:53

Judging History

你现在查看的是最新测评结果

  • [2024-02-26 16:02:53]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3952kb
  • [2024-02-26 16:02:53]
  • 提交

answer

#include <bits/stdc++.h>

using i64 = long long;
using i128 = __int128_t;

constexpr i64 inf = 1e12;

using P = std::complex<i64>;
auto dot(const P &a, const P &b) {
    return (std::conj(a) * b).real();
}
auto cross(const P &a, const P &b) {
    return (std::conj(a) * b).imag();
}
struct ConvexHull {
    std::vector<P> s;
    int pos = 0;
    void add(const P &x) {
        assert(s.empty() || s.back().real() <= x.real());
        while (s.size() >= 2 && cross(x - s.back(), x - s.end()[-2]) <= 0) {
            s.pop_back();
        }
        s.push_back(x);
    }
    i64 lst = -inf;
    i64 query(i64 x) {
        assert(lst <= x);
        lst = x;
        if (s.empty()) {
            return -inf;
        }
        P p(x, 1);
        while (pos + 1 < int(s.size()) && dot(s[pos], p) <= dot(s[pos + 1], p)) {
            ++pos;
        }
        return dot(s[pos], p);
    }
};

struct Interval {
    int l, r, b, e, x;
};
struct Solver {
    std::vector<std::vector<P>> sf;
    std::vector<std::vector<int>> sg;
    std::vector<ConvexHull> f, g;
    std::vector<P> points;
    Solver() {}
    void addF(int u, int l, int r, int p, const P &x) {
        sf[u].push_back(x);
        if (p == r - 1) {
            std::reverse(sf[u].begin(), sf[u].end());
            for (auto x : sf[u]) {
                f[u].add(x);
            }
        }
        if (r - l == 1) {
            return;
        }
        int m = (l + r) / 2;
        if (p < m) {
            addF(u << 1, l, m, p, x);
        } else {
            addF(u << 1 | 1, m, r, p, x);
        }
    }
    void addG(int u, int l, int r, int ql, int qr, int x) {
        if (r <= ql || qr <= l) {
            return;
        }
        if (ql <= l && r <= qr) {
            sg[u].push_back(x);
            return;
        }
        int m = (l + r) / 2;
        addG(u << 1, l, m, ql, qr, x);
        addG(u << 1 | 1, m, r, ql, qr, x);
    }
    i64 queryF(int u, int l, int r, int ql, int qr, i64 x) {
        if (r <= ql || qr <= l) {
            return -inf;
        }
        if (ql <= l && r <= qr) {
            return f[u].query(x);
        }
        int m = (l + r) / 2;
        return std::max(queryF(u << 1, l, m, ql, qr, x), queryF(u << 1 | 1, m, r, ql, qr, x));
    }
    i64 queryG(int u, int l, int r, int p, i64 x) {
        if (p == l) {
            for (auto x : sg[u]) {
                g[u].add(points[x]);
            }
        }
        i64 res = g[u].query(x);
        if (r - l > 1) {
            int m = (l + r) / 2;
            if (p < m) {
                res = std::max(res, queryG(u << 1, l, m, p, x));
            } else {
                res = std::max(res, queryG(u << 1 | 1, m, r, p, x));
            }
        }
        return res;
    }
    void solve(int n, const std::vector<i64> &sum, const std::vector<Interval> &intervals) {
        sf.resize(4 << std::__lg(n));
        f.resize(4 << std::__lg(n));
        sg.resize(4 << std::__lg(n + 1));
        g.resize(4 << std::__lg(n + 1));

        const int m = int(intervals.size());
        points.resize(m);
        std::vector<int> ord(m);
        std::iota(ord.begin(), ord.end(), 0);
        std::sort(ord.begin(), ord.end(), [&](int x, int y) {
            return intervals[x].x < intervals[y].x;
        });
        for (auto i : ord) {
            addG(1, 0, n + 1, intervals[i].b, intervals[i].e, i);
        }

        std::sort(ord.begin(), ord.end(), [&](int x, int y) {
            return intervals[x].b < intervals[y].b;
        });
        for (int i = 0, j = 0; i <= n; ++i) {
            i64 dp = i == 0 ? 0 : queryG(1, 0, n + 1, i, sum[i]);
            // std::cerr << dp << " ";
            if (i == n) {
                std::cout << dp << "\n";
                return;
            }
            addF(1, 0, n, i, P(-sum[i], dp));
            while (j < m && intervals[ord[j]].b == i + 1) {
                auto v = intervals[ord[j]];
                // std::cerr << i << ": " << ord[j] << " " << v.l << " " << v.r << " = " <<
                // queryF(1, 0, n, v.l, v.r, v.x) << "\n";
                points[ord[j]] = P(v.x, queryF(1, 0, n, v.l, v.r, v.x));
                assert(points[ord[j]].imag() >= -inf / 2);
                // std::cerr << ord[j] << ": " << points[ord[j]] << "\n";
                ++j;
            }
        }
    }
};

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    int n, k;
    std::cin >> n >> k;

    std::vector<int> a(n);
    std::vector<std::vector<int>> pos(n + 1, {-1});
    for (int i = 0; i < n; ++i) {
        std::cin >> a[i];
        pos[a[i]].push_back(i);
    }

    std::map<int, int> mp;
    for (int i = 0; i <= n; ++i) {
        mp[i] = i;
    }
    std::vector<Interval> intervals;
    auto add = [&](int l, int r, int b, int e, int x) {
        // L: [l, r), R: [b, e), mex[L, R) = x
        l = std::max(l, b - k);
        if (l >= r || b - r >= k) {
            return;
        }
        intervals.push_back({l, r, b, std::min(e, l + k + 1), x});
        for (int i = l + k + 1; i < e && i - r < k; ++i) {
            intervals.push_back({i - k, r, i, i + 1, x});
        }
    };
    for (int x = 0; x <= n; ++x) {
        pos[x].push_back(n);
        for (int i = 0; i < int(pos[x].size()) - 1; ++i) {
            int l = pos[x][i] + 1, r = pos[x][i + 1];
            int v = std::prev(mp.upper_bound(l))->second;
            if (v >= r) {
                continue;
            }
            for (auto it = mp.emplace(l, v).first; it->second < r; it = mp.erase(it)) {
                add(it->first, std::next(it)->first, it->second + 1, r + 1, x);
            }
            mp[l] = r;
        }
    }

    std::vector<i64> sum(n + 1);
    for (int i = 0; i < n; ++i) {
        sum[i + 1] = sum[i] + a[i];
    }

    // for (auto [l, r, b, e, x] : intervals) {
    //     std::cerr << l << " " << r << " " << b << " " << e << " " << x << "\n";
    // }

    Solver().solve(n, sum, intervals);

    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3640kb

input:

5 3
3 4 0 0 3

output:

10

result:

ok 1 number(s): "10"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3608kb

input:

8 4
0 1 2 0 3 1 4 1

output:

26

result:

ok 1 number(s): "26"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3584kb

input:

10 5
0 2 0 1 2 1 0 2 2 1

output:

33

result:

ok 1 number(s): "33"

Test #4:

score: 0
Accepted
time: 0ms
memory: 3596kb

input:

20 10
3 1 3 2 3 3 0 1 3 0 2 3 3 3 3 1 3 0 0 3

output:

160

result:

ok 1 number(s): "160"

Test #5:

score: 0
Accepted
time: 1ms
memory: 3608kb

input:

30 10
14 15 10 1 14 1 8 0 12 8 6 15 1 8 9 12 15 10 11 12 7 10 10 3 3 10 8 14 13 13

output:

172

result:

ok 1 number(s): "172"

Test #6:

score: 0
Accepted
time: 1ms
memory: 3608kb

input:

40 3
0 4 2 4 3 1 5 5 2 3 4 2 1 1 1 5 5 4 1 3 3 0 1 0 2 0 1 4 2 1 5 3 0 4 0 0 0 5 3 3

output:

51

result:

ok 1 number(s): "51"

Test #7:

score: 0
Accepted
time: 0ms
memory: 3664kb

input:

50 20
29 6 30 26 8 11 22 26 24 8 30 25 19 12 28 19 28 4 13 9 2 23 30 15 21 5 30 5 19 17 25 29 2 28 20 16 0 4 26 23 22 30 3 25 29 5 29 24 11 27

output:

378

result:

ok 1 number(s): "378"

Test #8:

score: 0
Accepted
time: 1ms
memory: 3700kb

input:

80 15
2 13 20 11 12 10 19 17 3 7 10 2 14 11 9 17 19 11 17 15 10 18 11 11 14 5 20 8 8 12 13 17 14 19 11 20 13 2 12 2 19 12 6 7 3 4 11 16 1 12 4 16 17 4 1 2 5 11 17 12 13 7 8 12 2 4 15 20 18 1 1 13 1 14 6 5 20 12 12 11

output:

0

result:

ok 1 number(s): "0"

Test #9:

score: 0
Accepted
time: 0ms
memory: 3952kb

input:

100 30
41 50 33 22 1 34 7 14 31 44 46 49 49 23 33 12 9 41 25 23 22 1 49 45 45 8 10 49 37 23 48 17 32 44 38 21 29 27 23 27 47 44 6 12 7 2 18 12 9 43 20 26 26 8 14 25 18 48 2 41 49 7 48 38 10 45 34 27 17 12 1 19 9 29 50 13 25 21 9 13 26 15 6 9 5 13 47 30 26 17 40 0 21 6 25 24 22 31 43 16

output:

1308

result:

ok 1 number(s): "1308"

Test #10:

score: 0
Accepted
time: 1ms
memory: 3756kb

input:

200 30
1 26 8 2 6 36 43 49 15 48 39 7 12 18 28 46 13 6 24 17 43 44 31 17 30 5 40 19 13 24 26 1 23 39 34 29 28 2 22 23 32 21 32 5 38 11 18 10 15 14 16 7 40 40 35 30 8 3 46 25 36 50 13 37 16 42 39 9 24 5 8 2 15 17 24 35 39 26 5 24 39 23 47 17 23 49 21 30 36 46 26 15 0 24 23 25 12 16 12 18 42 30 20 0 5...

output:

3389

result:

ok 1 number(s): "3389"

Test #11:

score: -100
Wrong Answer
time: 1ms
memory: 3924kb

input:

300 30
39 28 33 6 10 36 27 31 1 1 9 41 27 39 48 30 43 49 0 11 39 36 15 40 43 28 18 15 17 23 4 9 37 32 5 34 3 4 45 44 18 24 6 23 18 21 40 7 18 38 35 14 5 44 4 10 25 34 14 8 23 43 28 11 22 13 44 16 30 49 40 13 21 32 50 30 29 31 27 35 1 30 10 49 42 33 46 30 47 48 13 5 5 41 22 3 26 26 33 20 34 41 46 27 ...

output:

6566

result:

wrong answer 1st numbers differ - expected: '6636', found: '6566'