-
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.
- Loading branch information
old-yan
committed
Sep 22, 2023
1 parent
673231d
commit 649903e
Showing
56 changed files
with
3,474 additions
and
293 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
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
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,98 @@ | ||
#include "IO/FastIO.h" | ||
#include "TREE/AdjDiffTree.h" | ||
#include "TREE/FlatTree.h" | ||
|
||
// 手动模式 | ||
void Ad_manual() { | ||
// 树可以是 FlatTree LinkTree 或者 VectorTree 均可 | ||
// 一个无权树 | ||
OY::FlatTree::Tree<bool, 100000> T(6); | ||
// 加边 | ||
T.add_edge(0, 1); | ||
T.add_edge(0, 2); | ||
T.add_edge(0, 3); | ||
T.add_edge(3, 4); | ||
T.add_edge(3, 5); | ||
// 预备 | ||
T.prepare(); | ||
T.set_root(0); | ||
cout << T << endl; | ||
|
||
// 假定每个点的初值都是编号 * 100000 | ||
OY::AdjDiffTree::Table<int, decltype(T), false, 100000> Ad(&T, [&](int i) { | ||
return i * 100000; | ||
}); | ||
cout << Ad << endl; | ||
|
||
// 子树增值 | ||
Ad.switch_to_difference_downward(); | ||
Ad.add_subtree(3, 1); | ||
Ad.switch_to_value(); | ||
cout << Ad << endl; | ||
|
||
// 路径增值 | ||
Ad.switch_to_difference_upward(); | ||
Ad.add_path(1, 4, 0, -1, 10); | ||
Ad.switch_to_value(); | ||
cout << Ad << endl; | ||
|
||
// 查询子树和 | ||
Ad.switch_to_presum_upward(); | ||
cout << "sum of subtree(3) = " << Ad.query_subtree(3) << endl; | ||
|
||
// 查询路径和 | ||
Ad.switch_to_presum_downward(); | ||
cout << "sum of path(1~4) = " << Ad.query_path(1, 4, 0, -1) << endl; | ||
} | ||
|
||
// 自动模式 | ||
void Ad_auto() { | ||
OY::FlatTree::Tree<bool, 100000> T(6); | ||
T.add_edge(0, 1); | ||
T.add_edge(0, 2); | ||
T.add_edge(0, 3); | ||
T.add_edge(3, 4); | ||
T.add_edge(3, 5); | ||
T.prepare(); | ||
T.set_root(0); | ||
cout << T << endl; | ||
|
||
OY::AdjDiffTree::Table<int, decltype(T), true, 100000> Ad(&T, [&](int i) { | ||
return i * 100000; | ||
}); | ||
cout << Ad << endl; | ||
|
||
// 子树增值 | ||
Ad.add_subtree(3, 1); | ||
cout << Ad << endl; | ||
|
||
// 路径增值 | ||
Ad.add_path(1, 4, 0, -1, 10); | ||
cout << Ad << endl; | ||
|
||
// 查询子树和 | ||
cout << "sum of subtree(3) = " << Ad.query_subtree(3) << endl; | ||
|
||
// 查询路径和 | ||
cout << "sum of path(1~4) = " << Ad.query_path(1, 4, 0, -1) << endl; | ||
} | ||
|
||
int main() { | ||
Ad_manual(); | ||
Ad_auto(); | ||
} | ||
/* | ||
#输出如下 | ||
[0[1][2][3[4][5]]] | ||
[0[100000][200000][300000[400000][500000]]] | ||
[0[100000][200000][300001[400001][500001]]] | ||
[10[100010][200000][300011[400011][500001]]] | ||
sum of subtree(3) = 1200023 | ||
sum of path(1~4) = 800042 | ||
[0[1][2][3[4][5]]] | ||
[0[100000][200000][300000[400000][500000]]] | ||
[0[100000][200000][300001[400001][500001]]] | ||
[10[100010][200000][300011[400011][500001]]] | ||
sum of subtree(3) = 1200023 | ||
sum of path(1~4) = 800042 | ||
*/ |
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,133 @@ | ||
#include "IO/FastIO.h" | ||
#include "TREE/Centroid.h" | ||
#include "TREE/FlatTree.h" | ||
|
||
void test_centroid() { | ||
OY::FlatTree::Tree<bool, 100000> T(10); | ||
T.add_edge(0, 1); | ||
T.add_edge(1, 2); | ||
T.add_edge(2, 3); | ||
T.add_edge(3, 4); | ||
T.add_edge(4, 5); | ||
T.add_edge(5, 6); | ||
T.add_edge(6, 7); | ||
T.add_edge(7, 8); | ||
T.add_edge(8, 9); | ||
T.prepare(); | ||
T.set_root(0); | ||
cout << T << endl; | ||
|
||
// 找重心 | ||
auto centroid = OY::Centroid::Centroid<decltype(T), 100000>(&T).centroid(); | ||
cout << "first centroid = " << centroid.first << endl; | ||
cout << "second centroid = " << centroid.second << endl; | ||
|
||
T.resize(9); | ||
T.add_edge(0, 1); | ||
T.add_edge(1, 2); | ||
T.add_edge(2, 3); | ||
T.add_edge(3, 4); | ||
T.add_edge(4, 5); | ||
T.add_edge(5, 6); | ||
T.add_edge(6, 7); | ||
T.add_edge(7, 8); | ||
T.prepare(); | ||
T.set_root(0); | ||
cout << T << endl; | ||
|
||
// 找重心 | ||
centroid = OY::Centroid::Centroid<decltype(T), 100000>(&T).centroid(); | ||
cout << "first centroid = " << centroid.first << endl; | ||
// 此时只有一个重心 | ||
cout << "second centroid = " << int(centroid.second) << endl; | ||
} | ||
|
||
void test_tree_trie() { | ||
OY::FlatTree::Tree<bool, 100000> T(4); | ||
T.add_edge(0, 1); | ||
T.add_edge(0, 2); | ||
T.add_edge(0, 3); | ||
T.prepare(); | ||
cout << T << endl; | ||
|
||
// 以 0 为根时,给树中每个结点为根的子树的形态编号 | ||
auto ids = OY::Centroid::TreeTrie::get(T, 0); | ||
// 显然,叶子结点形态均相同,根结点独占一种形态 | ||
for (int i = 0; i < 4; i++) cout << "shape of " << i << " = " << ids[i] << endl; | ||
|
||
// 再建一棵树,把前面那棵树的形态给包含进去 | ||
T.resize(9); | ||
T.add_edge(8, 0); | ||
T.add_edge(0, 1); | ||
T.add_edge(0, 2); | ||
T.add_edge(8, 3); | ||
T.add_edge(8, 4); | ||
T.add_edge(4, 5); | ||
T.add_edge(4, 6); | ||
T.add_edge(4, 7); | ||
T.prepare(); | ||
cout << T << endl; | ||
|
||
// 以 8 为根时,给树中每个结点为根的子树的形态编号 | ||
ids = OY::Centroid::TreeTrie::get(T, 8); | ||
// 我们发现,以 4 为根的子树,和前面那棵树形态完全一致 | ||
for (int i = 0; i < 9; i++) cout << "shape of " << i << " = " << ids[i] << endl; | ||
} | ||
|
||
void test_centroid_decomposition() { | ||
// 重心分治/点分树,主要用法技巧在 oj 测试中体现,此处只建出点分树 | ||
OY::FlatTree::Tree<bool, 100000> T(10); | ||
T.add_edge(0, 1); | ||
T.add_edge(1, 2); | ||
T.add_edge(2, 3); | ||
T.add_edge(3, 4); | ||
T.add_edge(4, 5); | ||
T.add_edge(5, 6); | ||
T.add_edge(6, 7); | ||
T.add_edge(7, 8); | ||
T.add_edge(8, 9); | ||
T.prepare(); | ||
cout << T << endl; | ||
|
||
OY::FlatTree::Tree<bool, 100000> res(10); | ||
auto total_root = OY::Centroid::CentroidDecomposition<100000>::solve(T, {}, [&](int sub_centroid, int cur_centroid) { | ||
res.add_edge(sub_centroid, cur_centroid); | ||
}, | ||
{}); | ||
res.prepare(), res.set_root(total_root); | ||
// 显然,点分树比其原树,非常均衡 | ||
cout << res << endl; | ||
} | ||
|
||
int main() { | ||
test_centroid(); | ||
test_tree_trie(); | ||
test_centroid_decomposition(); | ||
} | ||
/* | ||
#输出如下 | ||
[0[1[2[3[4[5[6[7[8[9]]]]]]]]]] | ||
first centroid = 4 | ||
second centroid = 5 | ||
[0[1[2[3[4[5[6[7[8]]]]]]]]] | ||
first centroid = 4 | ||
second centroid = -1 | ||
[0[1][2][3]] | ||
shape of 0 = 1 | ||
shape of 1 = 0 | ||
shape of 2 = 0 | ||
shape of 3 = 0 | ||
[0[8[3][4[5][6][7]]][1][2]] | ||
shape of 0 = 2 | ||
shape of 1 = 0 | ||
shape of 2 = 0 | ||
shape of 3 = 0 | ||
shape of 4 = 1 | ||
shape of 5 = 0 | ||
shape of 6 = 0 | ||
shape of 7 = 0 | ||
shape of 8 = 3 | ||
[0[1[2[3[4[5[6[7[8[9]]]]]]]]]] | ||
[4[2[1[0]][3]][7[6[5]][8[9]]]] | ||
*/ |
Oops, something went wrong.