This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub kmyk/competitive-programming-library
/**
* @note 計算量は確かに落ちるのだけどこれを使って速くなるケースは元々全部連結してて自明な気がする
* @note thank to https://beta.atcoder.jp/contests/yahoo-procon2018-final/submissions/2126707
*/
struct range_union_find_tree {
vector<union_find_tree> data;
range_union_find_tree() = default;
explicit range_union_find_tree(size_t n) {
int log_n = 32 - __builtin_clz(n);
data.resize(log_n, union_find_tree(n));
}
/**
* @description unite (l1 + k)-th tree and (l2 + k)-th tree for each k in [0, len)
* @note O(1)
*/
void range_unite_trees(int l1, int l2, int len) {
int n = data.front().data.size();
assert (0 <= l1 and l1 + len <= n);
assert (0 <= l2 and l2 + len <= n);
assert (len >= 1);
int k = 31 - __builtin_clz(len); // log2
data[k].unite_trees(l1, l2);
data[k].unite_trees(l1 + len - (1 << k), l2 + len - (1 << k));
}
/**
* @description collapse range-queries and get result
* @note O(N \log N)
*/
union_find_tree const & update() {
int n = data.front().data.size();
int log_n = data.size();
REP_R (k, log_n - 1) {
REP (i, n - (1 << k)) {
int root = data[k + 1].find_root(i);
data[k].unite_trees(i, root);
data[k].unite_trees(i + (1 << k), root + (1 << k));
}
}
return data[0];
}
};
#line 1 "old/range-union-find-tree.inc.cpp"
/**
* @note 計算量は確かに落ちるのだけどこれを使って速くなるケースは元々全部連結してて自明な気がする
* @note thank to https://beta.atcoder.jp/contests/yahoo-procon2018-final/submissions/2126707
*/
struct range_union_find_tree {
vector<union_find_tree> data;
range_union_find_tree() = default;
explicit range_union_find_tree(size_t n) {
int log_n = 32 - __builtin_clz(n);
data.resize(log_n, union_find_tree(n));
}
/**
* @description unite (l1 + k)-th tree and (l2 + k)-th tree for each k in [0, len)
* @note O(1)
*/
void range_unite_trees(int l1, int l2, int len) {
int n = data.front().data.size();
assert (0 <= l1 and l1 + len <= n);
assert (0 <= l2 and l2 + len <= n);
assert (len >= 1);
int k = 31 - __builtin_clz(len); // log2
data[k].unite_trees(l1, l2);
data[k].unite_trees(l1 + len - (1 << k), l2 + len - (1 << k));
}
/**
* @description collapse range-queries and get result
* @note O(N \log N)
*/
union_find_tree const & update() {
int n = data.front().data.size();
int log_n = data.size();
REP_R (k, log_n - 1) {
REP (i, n - (1 << k)) {
int root = data[k + 1].find_root(i);
data[k].unite_trees(i, root);
data[k].unite_trees(i + (1 << k), root + (1 << k));
}
}
return data[0];
}
};