QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#616615#7787. Maximum RatingKdlyhWA 0ms3796kbC++207.0kb2024-10-06 09:15:352024-10-06 09:15:36

Judging History

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

  • [2024-10-06 09:15:36]
  • 评测
  • 测评结果:WA
  • 用时:0ms
  • 内存:3796kb
  • [2024-10-06 09:15:35]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iterator>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <stack>

#ifdef LOCAL
template <class T, size_t size = std::tuple_size<T>::value> std::string to_debug(T, std::string s = "") requires(not std::ranges::range<T>);
std::string to_debug(auto x) requires requires(std::ostream& os) { os << x; } { return static_cast<std::ostringstream>(std::ostringstream() << x).str(); }
std::string to_debug(std::ranges::range auto x, std::string s = "") requires(not std::is_same_v<decltype(x), std::string>) {
  for (auto xi : x) { s += ", " + to_debug(xi); }
  return "[" + s.substr(s.empty() ? 0 : 2) + "]";
}
template <class T, size_t size> std::string to_debug(T x, std::string s) requires(not std::ranges::range<T>) {
  [&]<size_t... I>(std::index_sequence<I...>) { ((s += ", " + to_debug(get<I>(x))), ...); }(std::make_index_sequence<size>());
  return "(" + s.substr(s.empty() ? 0 : 2) + ")";
}
#define debug(...) std::cerr << __LINE__ << ": (" #__VA_ARGS__ ") = " << to_debug(std::tuple(__VA_ARGS__)) << "\n"
#else
#define debug(x...)
#endif

using i64 = long long;

template <class T>
struct Discreter {
    std::vector<T> elementSet;

    Discreter(const std::vector<T> &a) : elementSet(a) {
        std::sort(begin(elementSet), end(elementSet));
        elementSet.erase(std::unique(begin(elementSet), end(elementSet)), end(elementSet));
    }

    std::vector<int> process(const std::vector<T> &a) const {//get the dicreter arr
        std::vector<int> discRes(a.size());

        for (int i = 0; i < a.size(); i++) {
            discRes[i] = query(a[i]);
        }

        return discRes;
    }

    int query(const T &x) const {
        auto it = std::lower_bound(begin(elementSet), end(elementSet), x);
        // assert(it != end(elementSet) and *it == x);

        return it - begin(elementSet);
    }

    int queryUpperBound(const T &x) const {
        auto it = std::upper_bound(begin(elementSet), end(elementSet), x);

        return it - begin(elementSet);
    }

    T queryInv(int index) const {
        return elementSet[index];
    }

    int size() {
        return elementSet.size();
    }
};

template<class Info>
struct SegmentTree {
    int n;
    std::vector<Info> info;
    SegmentTree() : n(0) {}
    SegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template<class T>
    SegmentTree(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());
        std::function<void(int, int, int)> build = [&](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init_[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void modify(int p, int l, int r, int x, const Info &v) {
        if (r - l == 1) {
            info[p] = info[p] + v;
            return;
        }
        int m = (l + r) / 2;
        if (x < m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l >= y || r <= x) {
            return Info();
        }
        if (l >= x && r <= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    int findFirst(int p, int l, int r, int x, int y, i64 tar) {
        if (l >= y || r <= x) {
            return -1;
        }
        if (l >= x && r <= y && (info[p].sum <= tar)) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findFirst(2 * p, l, m, x, y, tar);
        if (res == -1) {
            res = findFirst(2 * p + 1, m, r, x, y, tar - info[2 * p].sum);//把左边的所有贡献加起来,因为是求前缀和
        }
        return res;
    }
    int findFirst(int l, int r, i64 tar) {
        return findFirst(1, 0, n, l, r, tar);
    }
};

struct Info {
    i64 sum{}, cnt{};
};

Info operator + (const Info& a, const Info& b) {return {a.sum + b.sum, a.cnt + b.cnt};}

void solve()
{
    int n, Q; std::cin >> n >> Q; std::vector<int> a(n); for (auto& ai : a) {std::cin >> ai;}
    SegmentTree<Info> T(n + Q);
    std::vector<int> positives; for (auto& ai : a) {positives.push_back(ai);}
    std::vector<std::pair<int, int>> querires(Q); for (auto&[x, v] : querires) {
        std::cin >> x >> v; --x; if (v > 0) {positives.push_back(v);} 
    }

    Discreter discreter(positives);

    std::map<int, int> cnt; for (auto& ai : a) {cnt[ai] += 1;}
    for (auto&[ai, c] : cnt) {T.modify(discreter.query(ai), {c * ai, c});}

    i64 negative_abs_sum{}; 

    for (auto&[x, v] : querires) {
        //当前这个下标上对应的数的权值线段树的值
        //不一定就是单点赋值,而是把修改前的那个点减去一次a[x], 然后在新的v对应的上面加一次a=v
        
        if (a[x] <= 0) {negative_abs_sum -= std::abs(a[x]);}
        else {
            int id{discreter.query(a[x])};
            T.modify(id, {-a[x], -1});
        }
        if (v <= 0) {
            negative_abs_sum += std::abs(v);
        } else {
            int id{discreter.query(v)};
            T.modify(id, {v, 1});
        }

        int k{T.findFirst(0, n + Q, negative_abs_sum)};

        a[x] = v; 

        if (k == -1) {std::cout << T.rangeQuery(0, n + Q).cnt + 1 << "\n"; continue;}

        i64 pre_sum{T.rangeQuery(0, k).sum};

        int k_take{}, pre_take{T.rangeQuery(0, k).cnt};

        //第二遍找k取了多少个
        auto k_sum{T.rangeQuery(k, k + 1).sum};
        auto k_val{discreter.queryInv(k)};
        k_take = (negative_abs_sum - pre_sum) / k_val + 1;

        std::cout << k_take + pre_take << "\n";

    }

}
 
signed main()
{
    std::cin.tie(nullptr)->sync_with_stdio(false);
    int _{1};
#ifdef tests
    std::cin >> _;
#endif
    while(_--) solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

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: 3492kb

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: 3584kb

input:

1 1
1000000000
1 1000000000

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: -100
Wrong Answer
time: 0ms
memory: 3796kb

input:

1 1
-1000000000
1 -1000000000

output:

2

result:

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