結果
| 問題 |
No.789 範囲の合計
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-08-24 04:55:44 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,899 bytes |
| コンパイル時間 | 4,594 ms |
| コンパイル使用メモリ | 294,252 KB |
| 実行使用メモリ | 46,080 KB |
| 最終ジャッジ日時 | 2024-08-24 04:55:53 |
| 合計ジャッジ時間 | 7,943 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 7 WA * 8 |
ソースコード
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define debug(...) ((void)0)
#include <bits/stdc++.h>
template <class S, auto op, auto e, class Size = uint32_t>
struct sparse_segtree {
static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>, "op must work as S(S, S)");
static_assert(std::is_convertible_v<decltype(e), std::function<S()>>, "e must work as S()");
static_assert(std::is_unsigned_v<Size>, "Size must be a signed integral type");
sparse_segtree() : root(new node(nullptr)) {}
void set(int p, S x) {
root->set(p, x);
}
S get(int p) const {
return root->get(p);
}
S prod(int l, int r) const {
std::vector<const node*> v;
root->list(v, l, r);
S res = e();
for (const auto& n : v) {
res = op(res, n->val);
}
return res;
}
private:
static constexpr Size max_size = (Size(1) << Size(std::numeric_limits<Size>::digits - 1));
struct node {
node *parent, *left, *right;
S val;
explicit node(node* p) : parent(p), val(e()){};
void set(const Size p, S x, const Size cur_l = 0, const Size cur_r = max_size) {
if (cur_l + 1 == cur_r) {
val = x;
update();
return;
}
const Size cur_mid = std::midpoint(cur_l, cur_r);
// left
if (p < cur_mid) {
if (!left) left = new node(this);
left->set(p, x, cur_l, cur_mid);
return;
}
// right
if (!right) right = new node(this);
right->set(p, x, cur_mid, cur_r);
}
S get(const Size p, const Size cur_l = 0, const Size cur_r = max_size) const {
if (cur_l + 1 == cur_r) return val;
const Size cur_mid = std::midpoint(cur_l, cur_r);
// left
if (p < cur_mid) {
return left ? left->get(p, cur_l, cur_mid) : e();
}
// right
return right ? right->get(p, cur_mid, cur_r) : e();
}
void list(std::vector<const node*>& v, const Size l, const Size r, const Size cur_l = 0, const Size cur_r = max_size) const {
if (l <= cur_l && cur_r <= r) {
v.push_back(this);
return;
}
const Size cur_mid = std::midpoint(cur_l, cur_r);
if (r <= cur_mid) {
if (left) left->list(v, l, r, cur_l, cur_mid);
return;
}
if (cur_mid <= l) {
if (right) right->list(v, l, r, cur_mid, cur_r);
return;
}
if (left) left->list(v, l, r, cur_l, cur_mid);
if (right) right->list(v, l, r, cur_mid, cur_r);
}
void update() {
// if not a leaf, update val
if (left || right) {
val = e();
if (left) val = op(val, left->val);
if (right) val = op(val, right->val);
}
if (parent) parent->update();
}
};
node* root;
};
using namespace std;
using ll = long long;
using ld = long double;
using S = ll;
S op(S a, S b) { return a + b; }
S e() { return 0; }
using segtree = sparse_segtree<S, op, e>;
void solve(int) {
int q;
cin >> q;
segtree st;
ll ans = 0;
for (int i = 0; i < q; i++) {
int t;
cin >> t;
if (t == 0) {
int x, y;
cin >> x >> y;
st.set(x, st.get(x) + y);
continue;
}
if (t == 1) {
int l, r;
cin >> l >> r;
ans += st.prod(l, r + 1);
continue;
}
}
cout << ans << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve(0);
}