diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index dc3501e2..6a1ef84d 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -49,14 +49,6 @@ "tests/library_checker_aizu_tests/flow/dinic_lib_checker.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/hungarian.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/flow/min_cost_max_flow.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/connected_components_of_complement_graph.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/dijkstra_aizu.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/dijkstra_lib_checker.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/enumerate_triangles.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/graphs/hopcroft_karp_aizu.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2024-12-14 15:47:13 -0600", "tests/library_checker_aizu_tests/graphs/mst.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/graphs/offline_incremental_scc.test.cpp": "2024-12-14 15:47:13 -0600", "tests/library_checker_aizu_tests/graphs/strongly_connected_components_aizu.test.cpp": "2024-12-14 15:47:13 -0600", @@ -68,18 +60,10 @@ "tests/library_checker_aizu_tests/handmade_tests/edge_cd_small_trees.test.cpp": "2024-12-14 15:47:13 -0600", "tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/handmade_tests/functional_graph.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/handmade_tests/lca_ladder_forest.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/manacher.test.cpp": "2024-12-05 10:41:42 -0600", "tests/library_checker_aizu_tests/handmade_tests/merge_st_and_wavelet.test.cpp": "2024-11-19 08:31:51 -0600", "tests/library_checker_aizu_tests/handmade_tests/mobius.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/handmade_tests/permutation_tree_small.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/rmq_small_n.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/sa_find_subarray.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/seg_tree_find_small.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp": "2024-12-14 15:47:13 -0600", "tests/library_checker_aizu_tests/loops/chooses.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/loops/quotients.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/loops/submasks.test.cpp": "2024-11-17 14:04:03 -0600", @@ -101,28 +85,6 @@ "tests/library_checker_aizu_tests/math/solve_linear_mod.test.cpp": "2024-12-14 15:47:13 -0600", "tests/library_checker_aizu_tests/math/tetration.test.cpp": "2024-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/math/totient.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/math/xor_basis.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/math/xor_basis_intersection.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_binary_tree.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_k_ary_tree.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/monotonic_stack_related/count_rectangles.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/monotonic_stack_related/max_rect_histogram.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/kmp.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/strings/lcp_array.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/lcp_query_palindrome.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/lcs_dp.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/strings/lcs_queries.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/strings/lcs_queries_merge_sort_tree.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/strings/longest_common_substring.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/manacher.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/strings/multi_matching_bs.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/prefix_function.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/strings/sa_cmp.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/sa_sort_pairs.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/suffix_array.test.cpp": "2024-12-14 15:47:13 -0600", -"tests/library_checker_aizu_tests/strings/suffix_array_short.test.cpp": "2024-12-14 15:47:13 -0600", "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-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/trees/cd_jump_on_tree.test.cpp": "2024-12-14 15:47:13 -0600", diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index 66043a60..a119ba72 100644 --- a/library/graphs/bridges_cuts/block_vertex_tree.hpp +++ b/library/graphs/bridges_cuts/block_vertex_tree.hpp @@ -4,6 +4,9 @@ //! vector> adj(n); //! cuts cc(adj, m); //! vector bvt = block_vertex_tree(adj, cc); +//! vector>> adj1(n); +//! cuts cc1(adj1, m); +//! vector bvt1 = block_vertex_tree(adj1, cc1); //! //to loop over each unique bcc containing a node u: //! for (int bccid : bvt[v]) { //! bccid -= n; @@ -15,8 +18,9 @@ //! [n, n + num_bccs) are BCC nodes //! @time O(n + m) //! @time O(n) -vector block_vertex_tree( - const vector>& adj, const cuts& cc) { +template +vector block_vertex_tree(const G& adj, + const cuts& cc) { int n = sz(adj); vector bvt(n + cc.num_bccs); vector vis(cc.num_bccs); diff --git a/library/graphs/bridges_cuts/bridge_tree.hpp b/library/graphs/bridges_cuts/bridge_tree.hpp index a1c9978f..9b797a16 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -4,11 +4,15 @@ //! vector> adj(n); //! bridges br(adj, m); //! vector bt = bridge_tree(adj, br); +//! vector>> adj1(n); +//! bridges br1(adj1, m); +//! vector bt1 = bridge_tree(adj1, br1); //! @endcode //! @time O(n + m) //! @space O(n) -vector bridge_tree(const vector>& adj, - const bridges& br) { +template +vector bridge_tree(const G& adj, + const bridges& br) { vector tree(br.num_ccs); rep(i, 0, sz(adj)) for (auto [u, e_id] : adj[i]) if ( br.is_bridge[e_id]) tree[br.br_id[i]] diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index b6b53221..80f075ed 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -10,16 +10,19 @@ //! adj[v].emplace_back(u, i); //! } //! auto [num_ccs, is_bridge, br_id] = bridges(adj, m); +//! vector>> adj1(n); +//! auto [num_ccs1, is_bridge1, br_id1] = bridges(adj1, +//! m); //! @endcode //! is_bridge[edge id] = 1 iff bridge edge //! br_id[v] = id, 0<=id struct bridges { int num_ccs = 0; vector is_bridge; vi br_id; - bridges(const vector>& adj, int m): + bridges(const G& adj, int m): is_bridge(m), br_id(sz(adj), -1) { int n = sz(adj), timer = 1; vi tin(n), st; diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index 16c72675..9d4717eb 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -11,16 +11,18 @@ //! adj[v].emplace_back(u, i); //! } //! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m); +//! vector>> adj1(n); +//! auto [num_bccs1, is_cut1, bcc_id1] = cuts(adj1, m); //! @endcode //! is_cut[v] = 1 iff cut node //! bcc_id[edge id] = id, 0<=id struct cuts { int num_bccs = 0; vector is_cut; vi bcc_id; - cuts(const vector>& adj, int m): + cuts(const G& adj, int m): is_cut(sz(adj)), bcc_id(m, -1) { int n = sz(adj), timer = 1; vi tin(n), st; diff --git a/library/graphs/complement_graph_ccs.hpp b/library/graphs/complement_graph_ccs.hpp index da6d5e6b..8a725938 100644 --- a/library/graphs/complement_graph_ccs.hpp +++ b/library/graphs/complement_graph_ccs.hpp @@ -1,7 +1,9 @@ #pragma once //! @code //! vector adj(n); -//! auto cc_id = get_complement_graph_ccs(adj); +//! vi cc_id = get_complement_graph_ccs(adj); +//! vector> adj1; +//! vi cc_id2 = get_complement_graph_ccs(adj1); //! @endcode //! 0<=cc_id[v] &adj) { +template +vi get_complement_graph_ccs(const G& adj) { int n = sz(adj); vi cc_id(n), unseen(n); iota(all(unseen), 0); diff --git a/library/graphs/dijkstra.hpp b/library/graphs/dijkstra.hpp index 7db38c7a..e728c021 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -2,12 +2,14 @@ //! @code //! vector>> adj(n); //! auto d = dijkstra(adj, source); +//! vector>> adj1(n); +//! auto d1 = dijkstra(adj1, source); //! @endcode //! d[v] = min dist from source->..->v //! @time O(n + (m log m)) //! @space O(n + m) -vector dijkstra( - const vector>>& adj, int s) { +template +vector dijkstra(const G& adj, int s) { using p = pair; priority_queue, greater<>> pq; pq.emplace(0, s); diff --git a/library/graphs/hopcroft_karp.hpp b/library/graphs/hopcroft_karp.hpp index 919c1982..8c7cdd68 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -5,6 +5,8 @@ //! adj[l].push_back(r); // add edge l <-> r //! auto [matching_size, to_r, to_l, //! mvc_l, mvc_r] = hopcroft_karp(adj, rsz); +//! vector> adj1(lsz); +//! hopcroft_karp match(adj1, rsz); //! @endcode //! 0<=l to_r[l] in matching if to_r[l]!=-1 @@ -13,11 +15,11 @@ //! mvc_r[r] is 1 if r in Min Vertex Cover //! @time O(n + m * sqrt(n)) n = lsz + rsz //! @space O(n) -struct hopcroft_karp { +template struct hopcroft_karp { int m_sz = 0; vi to_r, to_l; vector mvc_l, mvc_r; - hopcroft_karp(const vector& adj, int rsz): + hopcroft_karp(const G& adj, int rsz): to_r(sz(adj), -1), to_l(rsz, -1) { int lsz = sz(adj); while (1) { diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 75baecd3..d658eb5f 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -3,15 +3,17 @@ //! @code //! vector adj(n); //! auto [num_sccs, scc_id] = sccs(adj); +//! vector> adj1(n); +//! auto [num_sccs1, scc_id1] = sccs(adj1); //! @endcode //! scc_id[v] = id, 0<=id v: scc_id[u] >= scc_id[v] //! @time O(n + m) //! @space O(n) -struct sccs { +template struct sccs { int num_sccs = 0; vi scc_id; - sccs(const vector& adj): scc_id(sz(adj), -1) { + sccs(const G& adj): scc_id(sz(adj), -1) { int n = sz(adj), timer = 1; vi tin(n), st; auto dfs = [&](auto&& self, int v) -> int { diff --git a/library/strings/knuth_morris_pratt.hpp b/library/strings/kmp.hpp similarity index 86% rename from library/strings/knuth_morris_pratt.hpp rename to library/strings/kmp.hpp index 0ec01063..c691faae 100644 --- a/library/strings/knuth_morris_pratt.hpp +++ b/library/strings/kmp.hpp @@ -1,8 +1,12 @@ #pragma once #include "prefix_function.hpp" //! @code +//! string s,t; //! KMP kmp(t); //! auto match = kmp.find_str(s); +//! vi s_vec,t_vec; +//! KMP kmp1(t_vec); +//! auto match2 = kmp1.find_str(s_vec); //! @endcode //! if match[i] == 1 then s[i,sz(t)) == t //! @time O(|s| + |t|) diff --git a/library/strings/longest_common_subsequence/lcs_queries.hpp b/library/strings/longest_common_subsequence/lcs_queries.hpp index 874a9917..4abe4bf3 100644 --- a/library/strings/longest_common_subsequence/lcs_queries.hpp +++ b/library/strings/longest_common_subsequence/lcs_queries.hpp @@ -1,8 +1,16 @@ #pragma once #include "../../data_structures/bit.hpp" #include "lcs_dp.hpp" -//! Given tuples (s_r, t_le, t_ri), find: -//! size(LCS(s[0,s_r), t[t_le,t_ri))) +//! @code +//! string s,t; +//! vi lcs_len = lcs_queries(s, t, queries); +//! vi s_vec,t_vec; +//! vi lcs_len1 = lcs_queries(s_vec, t_vec, queries); +//! @endcode +//! lcs_len[i] = size(LCS( +//! s[0,queries[i][0]), +//! t[queries[i][1],queries[i][2]) +//! )) //! @time O(n*m*log(m) + q*log(m) + q*log(q)) //! @space O(n + m + q) template diff --git a/library/strings/manacher/manacher.hpp b/library/strings/manacher/manacher.hpp index 3df712b2..566b0593 100644 --- a/library/strings/manacher/manacher.hpp +++ b/library/strings/manacher/manacher.hpp @@ -1,7 +1,10 @@ #pragma once //! https://codeforces.com/blog/entry/12143#comment-324162 //! @code +//! string s; //! auto man = manacher(s); +//! vi s_vec; +//! auto man1 = manacher(s_vec); //! @endcode //! //! man[center] = index of start of longest @@ -15,7 +18,7 @@ //! @space O(n) template vi manacher(const T& s) { int n = sz(s), p = 0; - vi man(max(0, 2 * n - 1)); + vi man(2 * n - 1); rep(i, 0, 2 * n - 1) { int r = i <= 2 * (p - man[p]) ? p - max(man[2 * p - i], man[p]) diff --git a/library/strings/suffix_array/compare/compare_substrings.hpp b/library/strings/suffix_array/compare/compare_substrings.hpp index 76f82ffe..b92b1007 100644 --- a/library/strings/suffix_array/compare/compare_substrings.hpp +++ b/library/strings/suffix_array/compare/compare_substrings.hpp @@ -1,6 +1,7 @@ #pragma once #include "compare_suffixes.hpp" //! @code +//! string s; //! auto [sa, sa_inv, lcp] = get_sa(s, 256); //! sa_query saq(s, sa, sa_inv, lcp); //! int cmp = saq.cmp_substrs(l1,r1,l2,r2); diff --git a/library/strings/suffix_array/compare/compare_suffixes.hpp b/library/strings/suffix_array/compare/compare_suffixes.hpp index 8fcda411..ee4bd3cc 100644 --- a/library/strings/suffix_array/compare/compare_suffixes.hpp +++ b/library/strings/suffix_array/compare/compare_suffixes.hpp @@ -1,5 +1,6 @@ #pragma once //! @code +//! string s; //! auto [sa, sa_inv, lcp] = get_sa(s, 256); //! sa_query saq(s, sa, sa_inv, lcp); //! int cmp = saq.cmp_sufs(l1,l2); diff --git a/library/strings/suffix_array/find/find_substring.hpp b/library/strings/suffix_array/find/find_substring.hpp index 6ae1ca32..0f8d0319 100644 --- a/library/strings/suffix_array/find/find_substring.hpp +++ b/library/strings/suffix_array/find/find_substring.hpp @@ -1,5 +1,6 @@ #pragma once //! @code +//! string s; //! auto [sa, sa_inv, lcp] = get_sa(s, 256); //! sa_query saq(s, sa, sa_inv, lcp); //! auto [sa_le,sa_ri] = saq.find_substr(s_l,s_r); diff --git a/library/strings/suffix_array/suffix_array.hpp b/library/strings/suffix_array/suffix_array.hpp index c42d39fc..27ff90be 100644 --- a/library/strings/suffix_array/suffix_array.hpp +++ b/library/strings/suffix_array/suffix_array.hpp @@ -25,11 +25,13 @@ //! lcp = {1, 3, 0, 0, 2} //! //! @code +//! // requires 0<=s[i] diff --git a/library/strings/suffix_array/suffix_array_query.hpp b/library/strings/suffix_array/suffix_array_query.hpp index 4e95130e..8444b010 100644 --- a/library/strings/suffix_array/suffix_array_query.hpp +++ b/library/strings/suffix_array/suffix_array_query.hpp @@ -3,9 +3,12 @@ #include "../../data_structures/rmq.hpp" #include "find/match.hpp" //! @code -//! //or sa_short +//! string s; //! auto [sa, sa_inv, lcp] = get_sa(s, 256); //! sa_query saq(s, sa, sa_inv, lcp); +//! vi s_vec; +//! auto [sa1, sa_inv1, lcp1] = sa_short(s_vec); +//! sa_query saq1(s_vec, sa1, sa_inv1, lcp1); //! @endcode template struct sa_query { int n; diff --git a/library/strings/suffix_array/suffix_array_short.hpp b/library/strings/suffix_array/suffix_array_short.hpp index 21e631a6..65c6044c 100644 --- a/library/strings/suffix_array/suffix_array_short.hpp +++ b/library/strings/suffix_array/suffix_array_short.hpp @@ -2,7 +2,10 @@ //! https://github.com/atcoder/ac-library/blob/master/atcoder/string.hpp //! @code //! // requires s[i]>=0 +//! string s; //! auto [sa, sa_inv, lcp] = sa_short(s); +//! vi s_vec; +//! auto [sa1, sa_inv1, lcp1] = sa_short(s_vec); //! @endcode //! runs in ~1.5s for 5e5 //! @time O(n * log^2(n)) diff --git a/library/strings/wildcard_pattern_matching.hpp b/library/strings/wildcard_pattern_matching.hpp index d69a5243..01a06727 100644 --- a/library/strings/wildcard_pattern_matching.hpp +++ b/library/strings/wildcard_pattern_matching.hpp @@ -1,6 +1,7 @@ #pragma once //! https://codeforces.com/blog/entry/111380 //! @code +//! vl s_vec, t_vec; //! auto mtch = wildcard_pattern_matching( //! s_vec, t_vec, conv); //! @endcode diff --git a/library/trees/centroid_decomp.hpp b/library/trees/centroid_decomp.hpp index 518ef68c..e531f85b 100644 --- a/library/trees/centroid_decomp.hpp +++ b/library/trees/centroid_decomp.hpp @@ -4,14 +4,18 @@ //! centroid(adj, [&](const vector& adj, //! int cent, int par_cent) { //! }); +//! vector> adj1(n); +//! centroid(adj1, +//! [&](const vector>& adj1, +//! int cent, int par_cent) {}); //! @endcode //! @time O(n log n) //! @space O(n) -template struct centroid { - vector adj; +template struct centroid { + G adj; F f; vi siz; - centroid(const vector& adj, F f): + centroid(const G& adj, F f): adj(adj), f(f), siz(sz(adj), -1) { rep(i, 0, sz(adj)) if (siz[i] == -1) dfs(i, -1); } diff --git a/library/trees/edge_cd.hpp b/library/trees/edge_cd.hpp index 7f0ffae0..85f6dbc1 100644 --- a/library/trees/edge_cd.hpp +++ b/library/trees/edge_cd.hpp @@ -11,15 +11,19 @@ //! // subtrees of suffix [split, sz(adj[cent])) //! // of adj[cent] are the second edge-set //! }); +//! vector> adj1(n); +//! edge_cd(adj1, [&]( +//! const vector>& adj1, +//! int cent, int split) {}); //! @endcode //! handle single-edge-paths separately //! @time O(n log1.5 n) //! @space O(n) -template struct edge_cd { - vector adj; +template struct edge_cd { + vector adj; F f; vi sub_sz; - edge_cd(const vector& adj, F f): + edge_cd(const vector& adj, F f): adj(adj), f(f), sub_sz(sz(adj)) { dfs(0, sz(adj)); } @@ -47,7 +51,7 @@ template struct edge_cd { return ret; }); f(adj, v, it - begin(adj[v])); - vi oth(it, end(adj[v])); + G oth(it, end(adj[v])); adj[v].erase(it, end(adj[v])); dfs(v, sum + 1); swap(adj[v], oth); diff --git a/library/trees/ladder_decomposition/linear_kth_par.hpp b/library/trees/ladder_decomposition/linear_kth_par.hpp index a4d36be6..b979ca26 100644 --- a/library/trees/ladder_decomposition/linear_kth_par.hpp +++ b/library/trees/ladder_decomposition/linear_kth_par.hpp @@ -1,21 +1,23 @@ #pragma once //! https://codeforces.com/blog/entry/126580 //! @code +//! vector adj(n); //! linear_kth_par kp(adj); //! int kth_par = kp.kth_par(v, k); +//! vector> adj1(n); +//! linear_kth_par kp1(adj1); //! @endcode //! kth_par = a node k edges up from v //! @time O(n + q) //! @space O(n) -struct linear_kth_par { +template struct linear_kth_par { struct node { int d, p = -1, dl, idx_j, idx_l; }; vector t; vector j; vi l; - linear_kth_par(const vector& adj): - t(sz(adj)), j(2 * sz(t)) { + linear_kth_par(const G& adj): t(sz(adj)), j(2 * sz(t)) { vi st; int pos = 1; auto add_j = [&]() -> void { diff --git a/library/trees/lca_rmq/lca_rmq.hpp b/library/trees/lca_rmq/lca_rmq.hpp index f579ea3b..653a3c75 100644 --- a/library/trees/lca_rmq/lca_rmq.hpp +++ b/library/trees/lca_rmq/lca_rmq.hpp @@ -4,17 +4,19 @@ //! @code //! vector adj(n); //! LCA lca(adj); +//! vector> adj1(n); +//! LCA lca1(adj1); //! @endcode //! @time O(nlogn + q) //! @space O(nlogn) // NOLINTNEXTLINE(readability-identifier-naming) -struct LCA { +template struct LCA { struct node { int in, sub_sz = 1, d, p = -1; }; vector t; RMQ> rmq = {{}, NULL}; - LCA(const vector& adj): t(sz(adj)) { + LCA(const G& adj): t(sz(adj)) { vi order; auto dfs = [&](auto&& self, int v) -> void { t[v].in = sz(order), order.push_back(v); diff --git a/library/trees/linear_kth_path.hpp b/library/trees/linear_kth_path.hpp index d99825a2..8b1af4cd 100644 --- a/library/trees/linear_kth_path.hpp +++ b/library/trees/linear_kth_path.hpp @@ -1,10 +1,10 @@ #pragma once #include "linear_lca.hpp" #include "ladder_decomposition/linear_kth_par.hpp" -struct linear_kth_path { - linear_lca lin_lca; - linear_kth_par lin_kp; - linear_kth_path(const vector& adj): +template struct linear_kth_path { + linear_lca lin_lca; + linear_kth_par lin_kp; + linear_kth_path(const G& adj): lin_lca(adj), lin_kp(adj) {} //! @param u,v endpoint nodes of path //! @param k index into path diff --git a/library/trees/linear_lca.hpp b/library/trees/linear_lca.hpp index f09faedf..ce722cb8 100644 --- a/library/trees/linear_lca.hpp +++ b/library/trees/linear_lca.hpp @@ -1,15 +1,20 @@ #pragma once //! https://codeforces.com/blog/entry/125371 +//! @code +//! vector adj(n); +//! linear_lca llca(adj); +//! vector> adj1(n); +//! linear_lca llca1(adj1); +//! @endcode //! @time O(n + q) //! @space O(n) -struct linear_lca { +template struct linear_lca { struct node { int d, label, asc; }; vector t; vi head; - linear_lca(const vector& adj): - t(sz(adj)), head(sz(t) + 1) { + linear_lca(const G& adj): t(sz(adj)), head(sz(t) + 1) { vector order; auto dfs = [&](auto&& self, int v, int p) -> void { order.emplace_back(v, p); diff --git a/library/trees/subtree_isomorphism.hpp b/library/trees/subtree_isomorphism.hpp index 7a99f00e..a81198a0 100644 --- a/library/trees/subtree_isomorphism.hpp +++ b/library/trees/subtree_isomorphism.hpp @@ -3,16 +3,18 @@ //! vector adj(n); //! auto [num_distinct_subtrees, iso_id] = //! subtree_iso(adj); +//! vector> adj1(n); +//! subtree_iso iso(adj1); //! @endcode //! - 0 <= iso_id[v] < num_distinct_subtrees //! - iso_id[u] == iso_id[v] iff subtree u is //! isomorphic to subtree v //! @time O(n log n) //! @space O(n) -struct subtree_iso { +template struct subtree_iso { int num_distinct_subtrees; vi iso_id; - subtree_iso(const vector& adj): iso_id(sz(adj), -1) { + subtree_iso(const G& adj): iso_id(sz(adj), -1) { map hashes; auto dfs = [&](auto&& self, int v, int p) -> int { vi ch_ids; diff --git a/library/trees/tree_lift/tree_lift.hpp b/library/trees/tree_lift/tree_lift.hpp index f88a3bbf..7fe4efd1 100644 --- a/library/trees/tree_lift/tree_lift.hpp +++ b/library/trees/tree_lift/tree_lift.hpp @@ -1,18 +1,21 @@ #pragma once //! https://github.com/ucf-programming-team/hackpack-cpp/blob/master/content/graphs/TreeLifting.h //! @code +//! vector adj(n); //! tree_lift tree_l(adj); //! int kth_p = tree_l.kth_par(v, k); +//! vector> adj1(n); +//! tree_lift tree_l1(adj1); //! @endcode //! kth_p = a node k edges up from v //! @time O(n + q log n) //! @space O(n) -struct tree_lift { +template struct tree_lift { struct node { int d, p = -1, j = -1; }; vector t; - tree_lift(const vector& adj): t(sz(adj)) { + tree_lift(const G& adj): t(sz(adj)) { auto dfs = [&](auto&& self, int v) -> void { int jump = (t[v].d + t[t[t[v].j].j].d == 2 * t[t[v].j].d) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index 7a1986b8..e20e98ca 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -5,10 +5,10 @@ assertWithSideEffect unknownMacro unusedStructMember:../library/flow/min_cost_max_flow.hpp unusedStructMember:../library/strings/suffix_array/find/match.hpp:10 -unusedStructMember:../library/trees/tree_lift/tree_lift.hpp:12 -unusedStructMember:../library/trees/ladder_decomposition/linear_kth_par.hpp:12 +unusedStructMember:../library/trees/tree_lift/tree_lift.hpp:15 +unusedStructMember:../library/trees/ladder_decomposition/linear_kth_par.hpp:15 unusedStructMember:../library/data_structures/dsu/dsu_bipartite.hpp:9 -unusedStructMember:../library/trees/linear_lca.hpp:7 +unusedStructMember:../library/trees/linear_lca.hpp:13 unusedScopedObject:../library/trees/centroid_decomp_uncommon/count_paths_per_length.hpp:12 unusedScopedObject:library_checker_aizu_tests/cd_asserts.hpp:5 unusedScopedObject:../library/trees/centroid_decomp_uncommon/count_paths_per_node.hpp:14 @@ -51,6 +51,7 @@ syntaxError:../library/loops/supermasks.hpp:8 syntaxError:../library/math/prime_sieve/mobius.hpp:6 syntaxError:../library/trees/lca_rmq/iterate_subtree.hpp:6 constVariable:../kactl/content/graph/CompressTree.h:20 -knownConditionTrueFalse:../library/strings/suffix_array/suffix_array.hpp:61 -knownConditionTrueFalse:../library/strings/suffix_array/suffix_array_short.hpp:26 +knownConditionTrueFalse:../library/strings/suffix_array/suffix_array.hpp:63 +knownConditionTrueFalse:../library/strings/suffix_array/suffix_array_short.hpp:29 constVariable:../kactl/content/numerical/NumberTheoreticTransform.h:30 +functionStatic:../library/monotonic_stack/monotonic_stack.hpp:11 diff --git a/tests/library_checker_aizu_tests/compress_tree_asserts.hpp b/tests/library_checker_aizu_tests/compress_tree_asserts.hpp index 935ade3e..2f32da3d 100644 --- a/tests/library_checker_aizu_tests/compress_tree_asserts.hpp +++ b/tests/library_checker_aizu_tests/compress_tree_asserts.hpp @@ -6,7 +6,7 @@ #undef LCA #include "../../library/contest/random.hpp" void compress_tree_asserts(vector> adj, - LCA& lc_rm) { + LCA>& lc_rm) { int n = sz(adj); vector used(n); KACTL_LCA kactl_lca(adj); diff --git a/tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp deleted file mode 100644 index 879beac2..00000000 --- a/tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#define PROBLEM \ - "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_1_A" -// since find_str_fast uses lower_bound in a weird way -// which makes the partition check fail -#undef _GLIBCXX_DEBUG -#include "../template.hpp" -#include "../../../library/strings/suffix_array/suffix_array_query.hpp" -#include "../../../library/strings/suffix_array/suffix_array_short.hpp" -#include "../../../library/strings/knuth_morris_pratt.hpp" -#include "../../../library/strings/manacher/longest_from_index.hpp" -#include "../../../library/strings/manacher/longest_palindrome_query.hpp" -#include "../../../library/strings/longest_common_subsequence/lcs_queries.hpp" -int main() { - cin.tie(0)->sync_with_stdio(0); - // mainly to test all strings algs compile when passing - // in vectors I had a bug where `compare` is only for - // strings, making `find_str` useless when using vectors - const int shift = 100'000; - vector arr(100); - for (int i = 0; i < 100; i++) arr[i] = shift + i; - auto [sa, sa_inv, lcp] = get_sa(arr, shift + 100); - sa_query sf_a(arr, sa, sa_inv, lcp); - { - for (int i = 1; i < 100; i++) - assert(sf_a.cmp_sufs(i - 1, i) < 0); - for (int i = 0; i < 99; i++) { - assert(sf_a.cmp_sufs(99, i) > 0); - assert(sf_a.cmp_sufs(i, 99) < 0); - assert(sf_a.cmp_sufs(i, i) == 0); - } - assert(sf_a.cmp_sufs(99, 99) == 0); - } - { - auto [sa_sht, sa_inv_sht, lcp_sht] = sa_short(arr); - assert(sa_sht == sa); - assert(sa_inv_sht == sa_inv); - assert(lcp == lcp_sht); - } - vector t(10); - for (int i = 50; i < 60; i++) t[i - 50] = shift + i; - { - auto [sa_le, sa_ri] = sf_a.find_str(t); - assert(sa_le == 50 && sa_ri == 51); - } - { - auto [sa_le, sa_ri, s_l, s_r] = sf_a.find_str_fast(t); - assert(sa_le == 50 && sa_ri == 51); - assert(s_l == 50 && s_r == 60); - } - for (int val : sf_a.lcp) assert(val == 0); - { - assert(sf_a.len_lcp(0, 99) == 0); - for (int i = 0; i < 100; i++) { - auto [sa_le, sa_ri, s_l, s_r] = - sf_a.find_substrs_concated({{i, i + 1}}); - pair short_res = - sf_a.find_substr(i, i + 1); - assert(sa_le == short_res.first && - sa_ri == short_res.second); - assert(sa_le == i && sa_ri == i + 1); - assert(s_l == i && s_r == i + 1); - } - for (int i = 0; i < 100; i++) { - auto [sa_le, sa_ri, s_l, s_r] = - sf_a.find_substrs_concated({{i, i}, {i, i}}); - pair short_res = sf_a.find_substr(i, i); - assert(sa_le == short_res.first && - sa_ri == short_res.second); - } - auto [sa_le, sa_ri, s_l, s_r] = - sf_a.find_substrs_concated({}); - assert(sa_le == 0 && sa_ri == sz(arr)); - assert(s_l == s_r); - assert(sf_a.cmp_substrs(0, 0, 99, 99) == 0); - assert(sf_a.cmp_substrs(5, 5, 47, 47) == 0); - assert(sf_a.cmp_substrs(50, 50, 99, 100) < 0); - assert(sf_a.cmp_substrs(50, 51, 20, 20) > 0); - assert(sf_a.cmp_substrs(0, 100, 0, 100) == 0); - assert(sf_a.cmp_substrs(1, 100, 0, 100) > 0); - assert(sf_a.cmp_substrs(0, 100, 1, 100) < 0); - } - { - KMP kmp(t); - vector is_m = kmp.find_str(arr); - assert(is_m[50]); - rep(i, 0, sz(is_m)) { - if (i == 50) continue; - assert(!is_m[i]); - } - } - { - pal_query pq(arr); - vector man(manacher(arr)), - longest(longest_from_index(pq)); - for (int i = 0; i < sz(man); i++) { - int sz = i - 2 * man[i] + 1; - assert(sz == (1 ^ (i & 1))); - } - for (int i = 0; i < 100; i++) { - assert(longest[i] == i); - assert(pq.is_pal(i, i)); - if (i + 2 <= 100) { - assert(!pq.is_pal(i, i + 1)); - if (i) assert(!pq.is_pal(i - 1, i + 1)); - } - } - longest_pal_query lpq(arr); - for (int l = 0; l < 100; l++) { - for (int r = l + 1; r <= 100; r++) { - auto [idx, len] = lpq.longest_pal(l, r); - assert(l <= idx && idx < r); - assert(len == 1); - } - } - } - { - vector> queries; - queries.push_back({100, 0, 100}); - vector res = lcs_queries(arr, arr, queries); - assert(res[0] == 100); - } - cout << "Hello World\n"; - return 0; -} diff --git a/tests/library_checker_aizu_tests/strings/README.md b/tests/library_checker_aizu_tests/strings/README.md deleted file mode 100644 index a8d49456..00000000 --- a/tests/library_checker_aizu_tests/strings/README.md +++ /dev/null @@ -1 +0,0 @@ -Most string algs are intended to work for both `std::string` and `std::vector`. To ensure they compile with `std::vector`'s, add them to [this test](../handmade_tests/string_with_vector.test.cpp). diff --git a/tests/library_checker_aizu_tests/strings/kmp.test.cpp b/tests/library_checker_aizu_tests/strings/kmp.test.cpp index 8db0badd..59e49afe 100644 --- a/tests/library_checker_aizu_tests/strings/kmp.test.cpp +++ b/tests/library_checker_aizu_tests/strings/kmp.test.cpp @@ -1,7 +1,7 @@ #define PROBLEM \ "https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/all/ALDS1_14_B" #include "../template.hpp" -#include "../../../library/strings/knuth_morris_pratt.hpp" +#include "../../../library/strings/kmp.hpp" int main() { cin.tie(0)->sync_with_stdio(0); string haystack, needle; diff --git a/tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp b/tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp index 5f8deff7..b8f01445 100644 --- a/tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp +++ b/tests/library_checker_aizu_tests/trees/kth_node_on_path.test.cpp @@ -2,7 +2,6 @@ "https://judge.yosupo.jp/problem/jump_on_tree" #include "../template.hpp" #include "../../../library/contest/random.hpp" -#include "../../../library/monotonic_stack/monotonic_stack.hpp" #include "../../../library/trees/tree_lift/tree_lift.hpp" #include "../../../library/trees/lca_rmq/lca_rmq.hpp" #include "../../../library/trees/linear_lca.hpp" @@ -12,7 +11,7 @@ int main() { cin.tie(0)->sync_with_stdio(0); int n, q; cin >> n >> q; - vector> adj(n); + vector adj(n); for (int i = 0; i < n - 1; i++) { int u, v; cin >> u >> v; diff --git a/tests/scripts/compile_commented_snippets.sh b/tests/scripts/compile_commented_snippets.sh index fbfea376..17ba92e5 100755 --- a/tests/scripts/compile_commented_snippets.sh +++ b/tests/scripts/compile_commented_snippets.sh @@ -18,16 +18,13 @@ git submodule update find ../library/ -type f -name "*.hpp" | grep --invert-match --file=.config/.code_snippet_excluded_file_list | sort | sed 's/^/#include "/; s/$/"/' | cpp -nostdinc -C -P | grep --invert-match --extended-regexp "const int mod = |const ll mod = " echo "int main() {" echo "vi a,b,subset;" - echo "vl left,bottom,s_vec,t_vec;" - echo "vector adj;" - echo "vector>> adj_w;" + echo "vl left,bottom;" echo "vector edges;" echo "vector> eds;" - echo "vector> w_eds;" + echo "vector> w_eds, queries;" echo "vector rhs;" echo "vector> mat;" echo "vector> grid;" - echo "string s,t;" echo "int n,m,k,tl,tr,l,r,l1,r1,l2,r2,s_l,s_r,root_l,root_r,source,sink,total_flow,bccid,u,v,lsz,rsz,cols,cap;" } >entire_library_without_main