This documentation is automatically generated by online-judge-tools/verification-helper
#include "data_structure/static_rectangle_sum.hpp"
2次元平面に値があり、長方形内に含まれる値の和を求めるクエリを静的に処理する。点の個数を $N$ 、クエリの個数を $Q$ としたとき、計算量は $O((N + Q)\log{N})$
$(x, y)$ に値 $val$ を加える。
$[l, r) \times [d, u)$ の長方形内に含まれる値の和を求めるクエリを追加する。
クエリを処理して、クエリを追加した順で処理結果を返す。
#pragma once
#include <array>
#include <tuple>
#include <vector>
#include "../data_structure/compress.hpp"
#include "../data_structure/fenwick_tree.hpp"
namespace ebi {
template <class S, class T> struct static_rectangle_sum {
private:
public:
static_rectangle_sum() = default;
void add_point(S x, S y, T val) {
p.emplace_back(x, y, val);
cp_x.add(x);
cp_y.add(y);
}
void add_query(S l, S d, S r, S u) {
q.push_back({l, d, r, u});
cp_x.add(l);
cp_x.add(r);
cp_y.add(d);
cp_y.add(u);
}
std::vector<T> run() {
assert(is_first);
is_first = false;
cp_x.build();
cp_y.build();
std::vector ptable(cp_x.size(), std::vector<int>());
std::vector qtable(cp_x.size(), std::vector(2, std::vector<int>()));
for (int i = 0; auto [x, y, val] : p) {
ptable[cp_x.get(x)].emplace_back(i);
i++;
}
for (int i = 0; auto [l, d, r, u] : q) {
qtable[cp_x.get(l)][0].emplace_back(i);
qtable[cp_x.get(r)][1].emplace_back(i);
i++;
}
std::vector<T> res(q.size(), 0);
fenwick_tree<T> ftree(cp_y.size());
for (int i = 0; i < cp_x.size(); i++) {
for (int j = 0; j < 2; j++) {
for (auto idx : qtable[i][j]) {
int d = q[idx][1], u = q[idx][3];
res[idx] +=
(j == 0 ? -1 : 1) * ftree.sum(cp_y.get(d), cp_y.get(u));
}
}
for (auto idx : ptable[i]) {
auto [x, y, val] = p[idx];
ftree.add(cp_y.get(y), val);
}
}
return res;
}
private:
bool is_first = true;
std::vector<std::tuple<S, S, T>> p;
std::vector<std::array<S, 4>> q;
compress<S> cp_x, cp_y;
};
} // namespace ebi
#line 2 "data_structure/static_rectangle_sum.hpp"
#include <array>
#include <tuple>
#include <vector>
#line 2 "data_structure/compress.hpp"
#include <algorithm>
#include <cassert>
#line 6 "data_structure/compress.hpp"
namespace ebi {
template <class T> struct compress {
private:
std::vector<T> cp;
public:
compress() = default;
compress(std::vector<T> cp_) : cp(cp_) {
build();
}
void build() {
std::sort(cp.begin(), cp.end());
cp.erase(std::unique(cp.begin(), cp.end()), cp.end());
}
void add(const T &val) {
cp.emplace_back(val);
}
int get(const T &val) const {
return std::lower_bound(cp.begin(), cp.end(), val) - cp.begin();
}
int size() const {
return cp.size();
}
bool find(const T &val) const {
auto itr = std::lower_bound(cp.begin(), cp.end(), val);
if (itr == cp.end())
return false;
else
return *itr == val;
}
T val(int idx) const {
assert(0 <= idx && idx < (int)cp.size());
return cp[idx];
}
};
} // namespace ebi
#line 2 "data_structure/fenwick_tree.hpp"
#line 5 "data_structure/fenwick_tree.hpp"
namespace ebi {
template <class T> struct fenwick_tree {
private:
int n;
std::vector<T> data;
public:
fenwick_tree(int _n) : n(_n), data(std::vector<T>(_n + 1, T(0))) {}
void add(int i, T val) {
i++;
for (int x = i; x <= n; x += x & -x) {
data[x] += val;
}
}
T prefix_sum(int i) const {
assert(0 <= i && i <= n);
T ret = 0;
for (int x = i; x > 0; x -= x & -x) {
ret += data[x];
}
return ret;
}
T sum(int l, int r) const {
return prefix_sum(r) - prefix_sum(l);
}
T all_sum() const {
return prefix_sum(n);
}
// prefix_sum(x) >= key となる最小のxを返す関数 O(log N)
int lower_bound(T key) {
if (key <= 0) return 0;
int x = 0;
int max = 1;
while ((max << 1) <= n) max <<= 1;
for (int k = max; k > 0; k >>= 1) {
if (x + k <= n && data[x + k] < key) {
x += k;
key -= data[x];
}
}
return x + 1;
}
};
} // namespace ebi
#line 9 "data_structure/static_rectangle_sum.hpp"
namespace ebi {
template <class S, class T> struct static_rectangle_sum {
private:
public:
static_rectangle_sum() = default;
void add_point(S x, S y, T val) {
p.emplace_back(x, y, val);
cp_x.add(x);
cp_y.add(y);
}
void add_query(S l, S d, S r, S u) {
q.push_back({l, d, r, u});
cp_x.add(l);
cp_x.add(r);
cp_y.add(d);
cp_y.add(u);
}
std::vector<T> run() {
assert(is_first);
is_first = false;
cp_x.build();
cp_y.build();
std::vector ptable(cp_x.size(), std::vector<int>());
std::vector qtable(cp_x.size(), std::vector(2, std::vector<int>()));
for (int i = 0; auto [x, y, val] : p) {
ptable[cp_x.get(x)].emplace_back(i);
i++;
}
for (int i = 0; auto [l, d, r, u] : q) {
qtable[cp_x.get(l)][0].emplace_back(i);
qtable[cp_x.get(r)][1].emplace_back(i);
i++;
}
std::vector<T> res(q.size(), 0);
fenwick_tree<T> ftree(cp_y.size());
for (int i = 0; i < cp_x.size(); i++) {
for (int j = 0; j < 2; j++) {
for (auto idx : qtable[i][j]) {
int d = q[idx][1], u = q[idx][3];
res[idx] +=
(j == 0 ? -1 : 1) * ftree.sum(cp_y.get(d), cp_y.get(u));
}
}
for (auto idx : ptable[i]) {
auto [x, y, val] = p[idx];
ftree.add(cp_y.get(y), val);
}
}
return res;
}
private:
bool is_first = true;
std::vector<std::tuple<S, S, T>> p;
std::vector<std::array<S, 4>> q;
compress<S> cp_x, cp_y;
};
} // namespace ebi