QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#616646 | #7787. Maximum Rating | Kdlyh | WA | 1ms | 3668kb | C++20 | 6.7kb | 2024-10-06 09:31:01 | 2024-10-06 09:31:03 |
Judging History
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;}
//离散化正数
std::vector<int> positives; auto get_positive = [&](auto& x) {if (x > 0) {positives.push_back(x);} return ;};
for (auto& ai : a) {get_positive(ai);}
std::vector<std::pair<int, int>> querires(Q); for (auto&[x, v] : querires) {std::cin >> x >> v; --x; get_positive(v);}
Discreter discreter(positives);
//建权值线段树
SegmentTree<Info> T(n + Q); for (auto& ai : a) if (ai > 0) {T.modify(discreter.query(ai), {ai, 1});}
i64 negative_abs_sum{}; for (auto&[x, v] : querires) {
//修改前
if (a[x] <= 0) {negative_abs_sum -= std::abs(a[x]);} else {T.modify(discreter.query(a[x]), {-a[x], -1});}
//修改后
if (v <= 0) {negative_abs_sum += std::abs(v);} else {T.modify(discreter.query(v), {v, 1});} a[x] = v;
//第一遍线段树二分,找到第一个大于负数绝对值的前缀和的下标
int k{T.findFirst(0, n + Q, negative_abs_sum)};
if (k == -1) {std::cout << T.rangeQuery(0, n + Q).cnt + 1 << "\n"; continue;}
//第二遍找k取了多少个
auto pre_sum{T.rangeQuery(0, k).sum};
auto pre_take{T.rangeQuery(0, k).cnt};
auto k_val{discreter.queryInv(k)};
i64 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: 1ms
memory: 3608kb
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: 3628kb
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: 3492kb
input:
1 1 1000000000 1 1000000000
output:
1
result:
ok 1 number(s): "1"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
1 1 -1000000000 1 -1000000000
output:
1
result:
ok 1 number(s): "1"
Test #5:
score: 0
Accepted
time: 1ms
memory: 3668kb
input:
1000 1000 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...
output:
946 65 252 410 915 592 983 487 343 899 809 432 586 587 139 464 804 84 476 699 504 149 579 352 375 856 545 166 140 657 568 509 275 710 873 430 537 879 301 1 298 970 923 510 984 642 55 879 941 344 464 788 917 994 571 610 491 442 926 101 986 840 624 613 425 345 816 423 275 221 317 113 386 116 469 260 4...
result:
ok 1000 numbers
Test #6:
score: -100
Wrong Answer
time: 1ms
memory: 3664kb
input:
1000 1000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000000 1 -1000000...
output:
352 221 133 13 137 210 141 149 25 267 242 227 295 344 13 6 58 265 85 309 340 469 20 368 336 481 402 143 389 215 458 60 481 341 390 476 118 288 262 357 488 407 243 145 495 164 34 419 92 24 327 135 176 113 144 310 100 112 314 295 26 458 151 240 314 345 376 23 22 365 78 212 134 112 123 175 204 434 415 ...
result:
wrong answer 1st numbers differ - expected: '500', found: '352'