QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#622222#7787. Maximum RatingRimuruChan#ML 0ms3596kbC++236.8kb2024-10-08 20:21:012024-10-08 20:21:02

Judging History

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

  • [2024-10-08 20:21:02]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:3596kb
  • [2024-10-08 20:21:01]
  • 提交

answer

#include <bits/stdc++.h>
#ifdef LOCAL_DEBUG
#include "debug.h"
#else
#define dbg(...) (void)0
#endif
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;

namespace skadi {

using i64 = long long;
template <class Info, class Tag>
class LazySegmentTree {
    int n;
    std::vector<Info> info;
    std::vector<Tag> tag;
    void apply(int p, int l, int r, Tag const& v) {
        info[p].apply(v, l, r);
        tag[p].apply(v, l, r);
    }
    void push(int p, int l, int r) {
        int m = (l + r) >> 1;
        apply(p << 1, l, m, tag[p]);
        apply(p << 1 | 1, m, r, tag[p]);
        tag[p] = Tag();
    }
    void pull(int p, int l, int r) {
        int m = (l + r) >> 1;
        info[p] = Info::merge(info[p << 1], info[p << 1 | 1], l, m, m, r);
    }
    void modify(int p, int l, int r, int x, Info const& v) {
        if (r - l == 1 && (info[p] = v, 1)) return;
        int m = (l + r) >> 1;
        push(p, l, r);
        if (x < m) modify(p << 1, l, m, x, v);
        else modify(p << 1 | 1, m, r, x, v);
        pull(p, l, r);
    }
    std::optional<Info> rangeQuery(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) return std::nullopt;
        if (l >= x && r <= y) return info[p];
        int m = (l + r) >> 1;
        push(p, l, r);
        auto lres = rangeQuery(p << 1, l, m, x, y);
        auto rres = rangeQuery(p << 1 | 1, m, r, x, y);
        if (!lres) return rres;
        if (!rres) return lres;
        return Info::merge(*lres, *rres, l, m, m, r);
    }
    void rangeApply(int p, int l, int r, int x, int y, Tag const& v) {
        if (l >= y || r <= x) return;
        if (l >= x && r <= y && (apply(p, l, r, v), 1)) return;
        int m = (l + r) >> 1;
        push(p, l, r);
        rangeApply(p << 1, l, m, x, y, v);
        rangeApply(p << 1 | 1, m, r, x, y, v);
        pull(p, l, r);
    }
    template <class F, bool REV>
    int find(int p, int l, int r, int x, int y, F&& pred) {
        if (l >= y || r <= x || !pred(l, r, info[p])) return -1;
        if (r - l == 1) return l;
        int m = (l + r) >> 1;
        push(p, l, r);
        int res = REV ? find<F, REV>(p << 1 | 1, m, r, x, y, std::forward<F>(pred))
                      : find<F, REV>(p << 1, l, m, x, y, std::forward<F>(pred));
        if (~res) return res;
        return REV ? find<F, REV>(p << 1, l, m, x, y, std::forward<F>(pred))
                   : find<F, REV>(p << 1 | 1, m, r, x, y, std::forward<F>(pred));
    }

public:
    LazySegmentTree() : n(0) {
    }
    LazySegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template <class T>
    LazySegmentTree(std::vector<T> init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template <class T>
    void init(std::vector<T> init_) {
        n = init_.size();
        info.assign(4 << std::__lg(n), Info());
        tag.assign(4 << std::__lg(n), Tag());
        std::function<void(int, int, int)> build = [&](int p, int l, int r) {
            if (r - l == 1 && (info[p] = init_[l], true)) return;
            int m = (l + r) >> 1;
            build(p << 1, l, m);
            build(p << 1 | 1, m, r);
            pull(p, l, r);
        };
        build(1, 0, n);
    }
    void modify(int p, Info const& v) {
        modify(1, 0, n, p, v);
    }
    std::optional<Info> rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    void rangeApply(int l, int r, const Tag& v) {
        return rangeApply(1, 0, n, l, r, v);
    }
    template <class F>
    int findFirst(int l, int r, F&& pred) {
        return find<F, false>(1, 0, n, l, r, std::forward<F>(pred));
    }
    template <class F>
    int findLast(int l, int r, F&& pred) {
        return find<F, true>(1, 0, n, l, r, std::forward<F>(pred));
    }
};

struct Tag {
    // i64 add = 0;
    void apply(Tag const& t, int l, int r) {
        // add += t.add;
    }
};

struct Info {
    i64 sum = 0;
    int cnt = 0;
    Info() = default;
    Info(i64 sum_, int cnt_) : sum(sum_), cnt(cnt_) {
    }
    void apply(Tag const& t, int l, int r) {
        // sum += t.add * (r - l);
    }
    static Info merge(Info const& a, Info const& b, int la, int ra, int lb, int rb) {
        return {a.sum + b.sum, a.cnt + b.cnt};
    }
};

void solve() {
    int n, q;
    std::cin >> n >> q;
    std::vector<int> a(n);
    std::vector<int> b(n + q);
    for (int i = 0; i < n; i++) {
        std::cin >> a[i];
        b[i] = a[i];
    }
    std::vector<std::pair<int, int>> queries(q);
    for (int i = 0; i < q; i++) {
        auto& [x, v] = queries[i];
        std::cin >> x >> v;
        x--;
        b[n + i] = v;
    }
    std::sort(b.begin(), b.end());
    auto is_neg = [](int x) {
        return x < 0;
    };
    b.erase(std::remove_if(b.begin(), b.end(), is_neg), b.end());
    b.erase(std::unique(b.begin(), b.end()), b.end());
    int t = 0, pos_cnt = 0;
    std::unordered_map<int, int> mp;
    for (int x : b) {
        mp[x] = t++;
    }
    i64 neg = 0;
    LazySegmentTree<Info, Tag> st(t);
    for (int i = 0; i < n; i++) {
        if (a[i] < 0) {
            neg += a[i];
        } else {
            pos_cnt++;
            auto q = *st.rangeQuery(mp[a[i]], mp[a[i]] + 1);
            st.modify(mp[a[i]], {q.sum + a[i], q.cnt + 1});
        }
    }
    std::vector<i64> ans(q);
    for (int i = 0; i < q; i++) {
        auto [x, v] = queries[i];
        if (a[x] < 0) {
            neg -= a[x];
        } else {
            pos_cnt--;
            auto q = *st.rangeQuery(mp[a[x]], mp[a[x]] + 1);
            st.modify(mp[a[x]], {q.sum - a[x], q.cnt - 1});
        }
        if (v < 0) {
            neg += v;
        } else {
            pos_cnt++;
            auto q = *st.rangeQuery(mp[v], mp[v] + 1);
            st.modify(mp[v], {q.sum + v, q.cnt + 1});
        }
        a[x] = v;

        auto p = st.findFirst(0, t, [&](int l, int r, Info const& i) {
            dbg(l, r, i.sum, i.cnt, neg);
            return i.sum + neg > 0;
        });
        dbg(p);
        int cnt = 0;
        if (p > 0) {
            auto q = *st.rangeQuery(0, p);
            cnt = q.cnt;
        }
        if (p == 0) {
            cnt = 0;
        }
        if (p == -1) {
            cnt = pos_cnt;
        }
        dbg(pos_cnt, cnt);
        ans[i] = cnt + 1;
    }
    for (auto x : ans) {
        std::cout << x << '\n';
    }
}

/*
3 5
1 2 3
3 4
2 -2
1 -3
3 1
2 1
 */

} // namespace skadi

int main() {
#ifndef LOCAL_DEBUG
    std::cin.tie(nullptr)->sync_with_stdio(false);
#endif
    int t = 1;
    // std::cin >> t;
    while (t--) {
        skadi::solve();
    }
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 3504kb

input:

3 5
1 2 3
3 4
2 -2
1 -3
3 1
2 1

output:

1
2
2
2
3

result:

ok 5 number(s): "1 2 2 2 3"

Test #2:

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

input:

3 5
1 2 3
3 4
2 -2
1 3
3 1
2 1

output:

1
2
1
2
1

result:

ok 5 number(s): "1 2 1 2 1"

Test #3:

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

input:

1 1
1000000000
1 1000000000

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: -100
Memory Limit Exceeded

input:

1 1
-1000000000
1 -1000000000

output:


result: