-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GlobalUnorderedDiscretizer; PARSC2D/PARSM2D/RAPSC2D/RAPSM2D;
- Loading branch information
old-yan
committed
May 9, 2024
1 parent
9695b28
commit fdeed8e
Showing
38 changed files
with
2,037 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/* | ||
最后修改: | ||
20240510 | ||
测试环境: | ||
gcc11.2,c++11 | ||
clang12.0,C++11 | ||
msvc14.2,C++14 | ||
*/ | ||
#ifndef __OY_GLOBALUNORDEREDDISCRETIZER__ | ||
#define __OY_GLOBALUNORDEREDDISCRETIZER__ | ||
|
||
#include "GlobalHashMap.h" | ||
|
||
namespace OY { | ||
template <typename Tp, GHASH::size_type BUFFER> | ||
struct GlobalUnorderedDiscretizer { | ||
using hash_table = GHASH::UnorderedMap<Tp, uint32_t, true, BUFFER>; | ||
using node = typename hash_table::node; | ||
hash_table m_hashmap; | ||
GHASH::size_type insert(const Tp &item) { | ||
auto res = m_hashmap.insert(item); | ||
if (res.m_flag) res.m_ptr->m_mapped = m_hashmap.size() - 1; | ||
return res.m_ptr->m_mapped; | ||
} | ||
GHASH::size_type find(const Tp &item) const { return m_hashmap.find(item)->m_mapped; } | ||
template <bool Check = true> | ||
GHASH::size_type rank(const Tp &item) { | ||
if constexpr (Check) | ||
return insert(item); | ||
else | ||
return find(item); | ||
} | ||
GHASH::size_type size() const { return m_hashmap.size(); } | ||
void clear() { m_hashmap.clear(); } | ||
template <typename Callback> | ||
void do_for_each(Callback &&call) { | ||
auto ptr_call = [&](node *p) { call(p->m_key); }; | ||
m_hashmap.do_for_each(ptr_call); | ||
} | ||
}; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
### 一、模板类别 | ||
|
||
数据结构:全局无序离散化 | ||
|
||
练习题目: | ||
|
||
1. [U428478 祖孙询问](https://www.luogu.com.cn/problem/U428478) | ||
|
||
### 二、模板功能 | ||
|
||
本模板建立于 `GlobalHashmap` 的基础上。当调用 `rank` 函数返回一个元素的离散化标号。 | ||
|
||
本模板与 `Discretizer` 模板的差别是,本模板为无序映射,不需要保证小元素对应小标号、大元素对应大标号。因此,并不需要等待全部元素插入完毕之后才能获取标号。 | ||
|
||
当调用 `rank` 函数时,若模板参数 `Check` 为 `true` ,会在获取标号时做检查;而当 `Check` 为 `false` ,不做检查。如果确信元素已经在表中,推荐将 `Check` 设为 `false` 。两个版本的 `rank` 函数可以被 `insert` 或者 `find` 代替。 | ||
|
||
|
||
### 三、模板示例 | ||
|
||
```c++ | ||
#include "DS/GlobalUnorderedDiscretizer.h" | ||
#include "IO/FastIO.h" | ||
|
||
OY::GlobalUnorderedDiscretizer<int, 1 << 10> D; | ||
int main() { | ||
cout << "22 -> " << D.insert(22) << endl; | ||
cout << "33 -> " << D.insert(33) << endl; | ||
cout << "11 -> " << D.insert(11) << endl; | ||
|
||
// 输出一下存在的元素 | ||
cout << "elems: "; | ||
D.do_for_each([](int x) { | ||
cout << x << ' '; | ||
}); | ||
cout << endl; | ||
} | ||
``` | ||
|
||
``` | ||
#输出如下 | ||
22 -> 0 | ||
33 -> 1 | ||
11 -> 2 | ||
elems: 22 33 11 | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
最后修改: | ||
20240506 | ||
测试环境: | ||
gcc11.2,c++11 | ||
clang12.0,C++11 | ||
msvc14.2,C++14 | ||
*/ | ||
#ifndef __OY_OFFLINEPOINTADDRECTSUMMAINTAINER2D__ | ||
#define __OY_OFFLINEPOINTADDRECTSUMMAINTAINER2D__ | ||
|
||
#include "PointAddRectSumCounter2D.h" | ||
|
||
namespace OY { | ||
namespace OFFLINEPARSM2D { | ||
using size_type = uint32_t; | ||
template <typename SizeType, typename WeightType = bool, typename SumType = typename std::conditional<std::is_same<WeightType, bool>::value, size_type, WeightType>::type> | ||
struct Solver { | ||
static constexpr bool is_bool = std::is_same<WeightType, bool>::value; | ||
using weight_type = typename std::conditional<is_bool, size_type, WeightType>::type; | ||
using inner_table = PARSC2D::Table<SizeType, weight_type, SumType, true>; | ||
struct event { | ||
bool m_flag; | ||
union { | ||
struct { | ||
size_type m_id; | ||
weight_type m_w; | ||
}; | ||
struct { | ||
SizeType m_x_min, m_x_max, m_y_min, m_y_max; | ||
}; | ||
} m_data; | ||
}; | ||
inner_table m_table; | ||
size_type m_point_id; | ||
std::vector<event> m_events; | ||
Solver(size_type point_cnt = 0, size_type op_cnt_since_query = 0) : m_table(point_cnt), m_point_id() { m_events.reserve(op_cnt_since_query); } | ||
void add_point(SizeType x, SizeType y, weight_type w = 1) { | ||
if (m_events.empty()) | ||
m_table.add_point(x, y, w); | ||
else { | ||
m_table.add_point(x, y, 0); | ||
event e; | ||
e.m_flag = false, e.m_data.m_id = m_point_id, e.m_data.m_w = w; | ||
m_events.push_back(e); | ||
} | ||
m_point_id++; | ||
} | ||
void add_query(SizeType x_min, SizeType x_max, SizeType y_min, SizeType y_max) { | ||
event e; | ||
e.m_flag = true, e.m_data.m_x_min = x_min, e.m_data.m_x_max = x_max, e.m_data.m_y_min = y_min, e.m_data.m_y_max = y_max; | ||
m_events.push_back(e); | ||
} | ||
std::vector<SumType> solve() { | ||
m_table.prepare(); | ||
std::vector<SumType> res; | ||
res.reserve(m_events.size()); | ||
for (auto &e : m_events) | ||
if (e.m_flag) | ||
res.push_back(m_table.query(e.m_data.m_x_min, e.m_data.m_x_max, e.m_data.m_y_min, e.m_data.m_y_max)); | ||
else | ||
m_table.add_point_value(e.m_data.m_id, e.m_data.m_w); | ||
return res; | ||
} | ||
}; | ||
}; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
### 一、模板类别 | ||
|
||
数据结构:离线二维【单点加,矩形区域和维护】表 | ||
|
||
练习题目: | ||
|
||
1. [#133. 二维树状数组 1:单点修改,区间查询](https://loj.ac/p/133) | ||
2. [Point Add Rectangle Sum](https://judge.yosupo.jp/problem/point_add_rectangle_sum)(https://github.com/yosupo06/library-checker-problems/issues/519) | ||
|
||
|
||
### 二、模板功能 | ||
|
||
本模板为 `PointAddRectSumMaintainer2D` 的离线版本,适用于加点和查询混杂的问题。 | ||
|
||
本模板提供了一个 `Solver` ,将区间信息和查询全部塞进去,即可获得查询结果。 | ||
|
||
类的模板参数有 `typename SizeType` 表示点的坐标类型; `typename WeightType` 表示点权类型; `typename SumType` 表示点权和的类型。 | ||
|
||
### 三、模板示例 | ||
|
||
```c++ | ||
#include "DS/OfflinePointAddRectSumMaintainer2D.h" | ||
#include "IO/FastIO.h" | ||
|
||
void test() { | ||
OY::OFFLINEPARSM2D::Solver<int, bool> S; | ||
S.add_query(-1, 1, -1, 1); | ||
S.add_query(0, 1, -1, 1); | ||
|
||
S.add_point(-1, -1); | ||
S.add_point(-1, 1); | ||
S.add_point(1, -1); | ||
S.add_point(1, 1); | ||
|
||
S.add_query(-1, 1, -1, 1); | ||
S.add_query(0, 1, -1, 1); | ||
|
||
auto res = S.solve(); | ||
|
||
cout << "before add points:\n"; | ||
cout << "sum of S{-1<=x<=1, -1<=y<=1}: " << res[0] << endl; | ||
cout << "sum of S{0<=x<=1, -1<=y<=1}: " << res[1] << endl; | ||
|
||
cout << "after add points:\n"; | ||
cout << "sum of S{-1<=x<=1, -1<=y<=1}: " << res[2] << endl; | ||
cout << "sum of S{0<=x<=1, -1<=y<=1}: " << res[3] << endl; | ||
} | ||
|
||
int main() { | ||
test(); | ||
} | ||
``` | ||
|
||
``` | ||
#输出如下 | ||
before add points: | ||
sum of S{-1<=x<=1, -1<=y<=1}: 0 | ||
sum of S{0<=x<=1, -1<=y<=1}: 0 | ||
after add points: | ||
sum of S{-1<=x<=1, -1<=y<=1}: 4 | ||
sum of S{0<=x<=1, -1<=y<=1}: 2 | ||
``` | ||
|
Oops, something went wrong.