QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#622328 | #7787. Maximum Rating | RimuruChan# | RE | 0ms | 3856kb | C++20 | 5.8kb | 2024-10-08 20:55:13 | 2024-10-08 20:55:14 |
Judging History
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 LazySegmentTree {
int n;
std::vector<Info> info;
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;
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;
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);
}
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;
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());
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);
}
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 Info {
i64 sum = 0;
int cnt = 0;
Info() = default;
Info(i64 sum_, int cnt_) : sum(sum_), cnt(cnt_) {
}
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;
}
auto is_neg = [](int x) {
return x < 0;
};
b.erase(std::remove_if(b.begin(), b.end(), is_neg), b.end());
std::sort(b.begin(), b.end());
b.erase(std::unique(b.begin(), b.end()), b.end());
int t = b.size(), pos_cnt = 0;
auto find = [&](int x) {
return std::lower_bound(b.begin(), b.end(), x) - b.begin();
};
i64 neg = 0, sum = 0;
LazySegmentTree<Info> st(t);
for (int i = 0; i < n; i++) {
if (a[i] < 0) {
neg += a[i];
} else {
sum += a[i];
pos_cnt++;
auto idx = find(a[i]);
auto q = *st.rangeQuery(idx, idx + 1);
st.modify(idx, {q.sum + a[i], q.cnt + 1});
}
}
for (int i = 0; i < q; i++) {
auto [x, v] = queries[i];
if (a[x] < 0) {
neg -= a[x];
} else {
sum -= a[x];
pos_cnt--;
auto idx = find(a[x]);
auto q = *st.rangeQuery(idx, idx + 1);
st.modify(idx, {q.sum - a[x], q.cnt - 1});
}
if (v < 0) {
neg += v;
} else {
sum += v;
pos_cnt++;
auto idx = find(v);
auto q = *st.rangeQuery(idx, idx + 1);
st.modify(idx, {q.sum + v, q.cnt + 1});
}
a[x] = v;
if (sum == 0) {
std::cout << 0 << '\n';
continue;
}
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;
});
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(p, cnt);
std::cout << cnt + 1 << '\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;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3816kb
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: 3856kb
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: 3648kb
input:
1 1 1000000000 1 1000000000
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: -100
Runtime Error
input:
1 1 -1000000000 1 -1000000000