This documentation is automatically generated by online-judge-tools/verification-helper
#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';
}
}
}