QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#616615 | #7787. Maximum Rating | Kdlyh | WA | 0ms | 3796kb | C++20 | 7.0kb | 2024-10-06 09:15:35 | 2024-10-06 09:15:36 |
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;}
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;
}
详细
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'