This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub hitonanode/cplib-cpp
#define PROBLEM "https://judge.yosupo.jp/problem/point_add_rectangle_sum" #include "../rangetree_bit.hpp" #include <iostream> #include <tuple> #include <vector> using namespace std; using S = unsigned long long; S e() noexcept { return 0; } void opadd(S &l, S r) noexcept { l += r; } void opsub(S &l, S r) noexcept { l -= r; } int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; std::vector<int> x(N), y(N), w(N); rangetree_bit<S, opadd, opsub, e, int> tree; for (int i = 0; i < N; i++) { cin >> x[i] >> y[i] >> w[i]; tree.add_point(x[i], y[i]); } std::vector<std::tuple<int, int, int, int, int>> qs; for (int i = 0; i < Q; i++) { int t; cin >> t; if (t == 0) { int x, y, w; cin >> x >> y >> w; qs.emplace_back(t, x, y, w, 0); tree.add_point(x, y); } else { int l, d, r, u; cin >> l >> d >> r >> u; qs.emplace_back(t, l, r, d, u); } } tree.build(); for (int i = 0; i < N; i++) tree.add(x[i], y[i], w[i]); for (auto q : qs) { if (std::get<0>(q) == 0) { int t, x, y, w, z; tie(t, x, y, w, z) = q; tree.add(x, y, w); } else { int t, l, r, d, u; tie(t, l, r, d, u) = q; cout << tree.sum(l, r, d, u) << '\n'; } } }
#line 1 "segmenttree/test/rangetree_bit.test.cpp" #define PROBLEM "https://judge.yosupo.jp/problem/point_add_rectangle_sum" #line 2 "segmenttree/rangetree_bit.hpp" #include <algorithm> #include <cassert> #include <utility> #include <vector> // CUT begin // 領域木 template <class S, void (*opadd)(S &, S), void (*opsub)(S &, S), S (*e)(), class Coordinate> class rangetree_bit { int n; std::vector<std::pair<Coordinate, Coordinate>> _pts; struct BIT { std::vector<S> data; BIT(int len) : data(len, e()) {} void add(int pos, S v) { for (pos++; pos and pos <= int(data.size()); pos += pos & -pos) opadd(data[pos - 1], v); } S sum(int r) const { S ret = e(); while (r) opadd(ret, data[r - 1]), r -= r & -r; return ret; } }; std::vector<std::vector<Coordinate>> _range2ys; std::vector<BIT> bits; void _add_singlenode(int v, Coordinate y, S val) { auto i = std::distance( _range2ys[v].begin(), std::lower_bound(_range2ys[v].begin(), _range2ys[v].end(), y)); bits[v].add(i, val); } S _get_singlenode(int v, Coordinate y) const { auto i = std::distance( _range2ys[v].begin(), std::lower_bound(_range2ys[v].begin(), _range2ys[v].end(), y)); return bits[v].sum(i); } S _sum(Coordinate xl, Coordinate xr, Coordinate yr) const { // [xl, xr) * (-INF, yr) auto compx = [](std::pair<Coordinate, Coordinate> l, std::pair<Coordinate, Coordinate> r) { return l.first < r.first; }; int l = n + std::distance(_pts.begin(), std::lower_bound(_pts.begin(), _pts.end(), std::make_pair(xl, yr), compx)); int r = n + std::distance(_pts.begin(), std::lower_bound(_pts.begin(), _pts.end(), std::make_pair(xr, yr), compx)); S ret = e(); while (l < r) { if (l & 1) opadd(ret, _get_singlenode(l++, yr)); if (r & 1) opadd(ret, _get_singlenode(--r, yr)); l >>= 1, r >>= 1; } return ret; } public: rangetree_bit() = default; void add_point(Coordinate x, Coordinate y) noexcept { _pts.emplace_back(x, y); } void build() { std::sort(_pts.begin(), _pts.end()); _pts.erase(std::unique(_pts.begin(), _pts.end()), _pts.end()); n = _pts.size(); _range2ys.resize(n * 2); for (int i = 0; i < n; i++) _range2ys[n + i] = {_pts[i].second}; for (int i = n - 1; i > 0; i--) { auto &lch = _range2ys[i * 2]; auto &rch = _range2ys[i * 2 + 1]; std::merge( lch.begin(), lch.end(), rch.begin(), rch.end(), std::back_inserter(_range2ys[i])); _range2ys[i].erase( std::unique(_range2ys[i].begin(), _range2ys[i].end()), _range2ys[i].end()); } for (const auto &v : _range2ys) bits.push_back(BIT(v.size())); } void add(Coordinate x, Coordinate y, S val) { int i = std::distance( _pts.begin(), std::lower_bound(_pts.begin(), _pts.end(), std::make_pair(x, y))); assert(i < n and _pts[i] == std::make_pair(x, y)); for (i += n; i; i >>= 1) _add_singlenode(i, y, val); } S sum(Coordinate xl, Coordinate xr, Coordinate yl, Coordinate yr) const { auto ret_r = _sum(xl, xr, yr); auto ret_l = _sum(xl, xr, yl); opsub(ret_r, ret_l); return ret_r; } }; #line 3 "segmenttree/test/rangetree_bit.test.cpp" #include <iostream> #include <tuple> #line 6 "segmenttree/test/rangetree_bit.test.cpp" using namespace std; using S = unsigned long long; S e() noexcept { return 0; } void opadd(S &l, S r) noexcept { l += r; } void opsub(S &l, S r) noexcept { l -= r; } int main() { cin.tie(nullptr), ios::sync_with_stdio(false); int N, Q; cin >> N >> Q; std::vector<int> x(N), y(N), w(N); rangetree_bit<S, opadd, opsub, e, int> tree; for (int i = 0; i < N; i++) { cin >> x[i] >> y[i] >> w[i]; tree.add_point(x[i], y[i]); } std::vector<std::tuple<int, int, int, int, int>> qs; for (int i = 0; i < Q; i++) { int t; cin >> t; if (t == 0) { int x, y, w; cin >> x >> y >> w; qs.emplace_back(t, x, y, w, 0); tree.add_point(x, y); } else { int l, d, r, u; cin >> l >> d >> r >> u; qs.emplace_back(t, l, r, d, u); } } tree.build(); for (int i = 0; i < N; i++) tree.add(x[i], y[i], w[i]); for (auto q : qs) { if (std::get<0>(q) == 0) { int t, x, y, w, z; tie(t, x, y, w, z) = q; tree.add(x, y, w); } else { int t, l, r, d, u; tie(t, l, r, d, u) = q; cout << tree.sum(l, r, d, u) << '\n'; } } }