Skip to content
Merged

Fixes #124

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .verify-helper/timestamps.remote.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@
"tests/library_checker_aizu_tests/handmade_tests/count_paths_forest.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/handmade_tests/dsu_size.test.cpp": "2024-12-14 19:50:29 -0600",
"tests/library_checker_aizu_tests/handmade_tests/dynamic_bitset.test.cpp": "2024-11-22 10:47:44 -0600",
"tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp": "2024-12-15 16:49:53 -0600",
"tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp": "2024-12-14 19:50:29 -0600",
"tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2024-12-15 16:56:37 -0600",
"tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2024-12-14 19:50:29 -0600",
"tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-14 19:50:29 -0600",
"tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2024-12-14 19:50:29 -0600",
Expand Down Expand Up @@ -125,9 +125,10 @@
"tests/library_checker_aizu_tests/strings/trie.test.cpp": "2024-12-05 10:41:42 -0600",
"tests/library_checker_aizu_tests/strings/wildcard_pattern_matching.test.cpp": "2024-12-14 19:50:29 -0600",
"tests/library_checker_aizu_tests/trees/count_paths_per_length.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_query.test.cpp": "2024-12-14 18:43:21 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_update.test.cpp": "2024-12-14 18:43:21 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_count_paths_per_length.test.cpp": "2024-12-14 18:43:21 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_query.test.cpp": "2024-12-15 16:49:53 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_contour_range_update.test.cpp": "2024-12-15 16:49:53 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_count_paths_per_length.test.cpp": "2024-12-15 16:49:53 -0600",
"tests/library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp": "2024-12-15 16:49:53 -0600",
"tests/library_checker_aizu_tests/trees/kth_path_ladder.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/trees/kth_path_linear.test.cpp": "2024-12-15 14:34:10 -0600",
"tests/library_checker_aizu_tests/trees/kth_path_tree_lift.test.cpp": "2024-12-15 14:34:10 -0600",
Expand Down
4 changes: 2 additions & 2 deletions library/graphs/functional_graph_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
//! https://github.com/Aeren1564/Algorithms/blob/master/Algorithm_Implementations_Cpp/Graph_Theory/Special_Graphs/functional_graph_processor.sublime-snippet
//! @code
//! // 0 <= a[i] < n
//! auto [t2, cycle] = func_graph(a);
//! auto [cyc_id, cyc_pos] = t2[v].root_of;
//! auto [t, cycle] = func_graph(a);
//! auto [cyc_id, cyc_pos] = t[v].root_of;
//! int root = cycle[cyc_id][cyc_pos];
//! bool is_on_cycle = (v == root);
//! @endcode
Expand Down
2 changes: 1 addition & 1 deletion tests/.config/.cppcheck_suppression_list
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ unusedScopedObject:../library/trees/centroid_decomp_uncommon/count_paths_per_nod
unusedScopedObject:library_checker_aizu_tests/trees/centroid_path_dist.test.cpp:29
unusedScopedObject:../library/trees/edge_centroid_decomp_uncommon/count_paths_per_length.hpp:13
unusedScopedObject:library_checker_aizu_tests/trees/edge_cd_lca.test.cpp:20
unusedScopedObject:library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp:48
unusedScopedObject:library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp:49
unusedScopedObject:library_checker_aizu_tests/trees/cd_jump_on_tree.test.cpp:20
unusedScopedObject:library_checker_aizu_tests/trees/cd_jump_on_tree.test.cpp:58
arrayIndexOutOfBoundsCond:library_checker_aizu_tests/math/linear_prime_sieve.test.cpp:17
Expand Down
4 changes: 2 additions & 2 deletions tests/library_checker_aizu_tests/edge_cd_asserts.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
void edge_cd_asserts(const vector<vector<int>>& adj,
int cent, int split) {
void edge_cd_asserts(const vector<vi>& adj, int cent,
int split) {
assert(0 < split && split < sz(adj[cent]));
auto dfs = [&](auto&& self, int u, int p) -> int {
int siz = 1;
Expand Down

This file was deleted.

56 changes: 28 additions & 28 deletions tests/library_checker_aizu_tests/trees/edge_cd_reroot_dp.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,34 @@
#include "../template.hpp"
#include "../edge_cd_asserts.hpp"
#include "../../../library/trees/edge_cd.hpp"
#include "../../../library/math/mod_int.hpp"
int main() {
cin.tie(0)->sync_with_stdio(0);
int n;
cin >> n;
vector<int> a(n);
vector<int64_t> res(n);
vector<mint> res(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
res[i] = a[i];
}
vector<vector<int>> adj(n);
vector<int> b(n - 1), c(n - 1);
vector<basic_string<int>> adj(n);
vector<mint> b(n - 1), c(n - 1);
vector<pair<int, int>> par(n, {-1, -1});
const int mod = 998'244'353;
vector<vector<int>> base_adj(n);
{
vector<vector<pair<int, int>>> adj_with_id(n);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v >> b[i] >> c[i];
cin >> u >> v >> b[i].x >> c[i].x;
adj[u].push_back(v);
adj[v].push_back(u);
base_adj[u].push_back(v);
base_adj[v].push_back(u);
adj_with_id[u].emplace_back(v, i);
adj_with_id[v].emplace_back(u, i);
res[u] += 1LL * b[i] * a[v] + c[i];
res[u] %= mod;
res[v] += 1LL * b[i] * a[u] + c[i];
res[v] %= mod;
res[u] = res[u] + b[i] * a[v] + c[i];
res[v] = res[v] + b[i] * a[u] + c[i];
}
auto dfs = [&](auto&& self, int u) -> void {
for (auto [v, e_id] : adj_with_id[u])
Expand All @@ -44,35 +45,34 @@ int main() {
assert(u_low ^ v_low);
return u_low ? par[u].second : par[v].second;
};
{ edge_cd(adj, edge_cd_asserts); }
{ edge_cd(base_adj, edge_cd_asserts); }
edge_cd(adj,
[&](const vector<vector<int>>& cd_adj, int cent,
[&](const vector<basic_string<int>>& cd_adj, int cent,
int split) -> void {
array<vector<array<int64_t, 3>>, 2> all_backwards;
array<int64_t, 2> sum_forward = {0, 0},
cnt_nodes = {0, 0};
array<vector<array<mint, 3>>, 2> all_backwards;
array<mint, 2> sum_forward = {0, 0};
array<int, 2> cnt_nodes = {0, 0};
auto dfs = [&](auto&& self, int u, int p,
array<int64_t, 2> forwards,
array<int64_t, 2> backwards,
array<mint, 2> forwards,
array<mint, 2> backwards,
int side) -> void {
all_backwards[side].push_back(
{u, backwards[0], backwards[1]});
sum_forward[side] +=
sum_forward[side] = sum_forward[side] +
forwards[0] * a[u] + forwards[1];
sum_forward[side] %= mod;
cnt_nodes[side]++;
for (int v : cd_adj[u]) {
if (v == p) continue;
int e_id = edge_id(u, v);
// f(x) = ax+b
// g(x) = cx+d
// f(g(x)) = a(cx+d)+b = acx+ad+b
array<int64_t, 2> curr_forw = {
forwards[0] * b[e_id] % mod,
(forwards[0] * c[e_id] + forwards[1]) % mod};
array<int64_t, 2> curr_backw = {
b[e_id] * backwards[0] % mod,
(b[e_id] * backwards[1] + c[e_id]) % mod};
array<mint, 2> curr_forw = {
forwards[0] * b[e_id],
forwards[0] * c[e_id] + forwards[1]};
array<mint, 2> curr_backw = {
backwards[0] * b[e_id],
backwards[1] * b[e_id] + c[e_id]};
self(self, v, u, curr_forw, curr_backw, side);
}
};
Expand All @@ -84,13 +84,13 @@ int main() {
for (int side = 0; side < 2; side++) {
for (
auto [u, curr_b, curr_c] : all_backwards[side]) {
res[u] += curr_b * sum_forward[!side] +
cnt_nodes[!side] * curr_c;
res[u] %= mod;
res[u.x] = res[u.x] +
curr_b * sum_forward[!side] +
curr_c * cnt_nodes[!side];
}
}
});
for (int i = 0; i < n; i++) cout << res[i] << ' ';
for (int i = 0; i < n; i++) cout << res[i].x << ' ';
cout << '\n';
return 0;
}
Loading