結果

問題 No.789 範囲の合計
ユーザー nu50218nu50218
提出日時 2024-08-24 05:41:18
言語 C++23(gcc13)
(gcc 13.2.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,897 bytes
コンパイル時間 4,710 ms
コンパイル使用メモリ 293,624 KB
実行使用メモリ 46,080 KB
最終ジャッジ日時 2024-08-24 05:41:25
合計ジャッジ時間 6,877 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
6,812 KB
testcase_01 AC 2 ms
6,944 KB
testcase_02 WA -
testcase_03 WA -
testcase_04 AC 176 ms
45,952 KB
testcase_05 AC 148 ms
39,552 KB
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 AC 140 ms
46,080 KB
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 AC 2 ms
6,940 KB
testcase_14 AC 2 ms
6,940 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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) {
            ll x, y;
            cin >> x >> y;
            st.set(x, st.get(x) + y);
            continue;
        }

        if (t == 1) {
            ll 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);
}
0