From 31974eeca9d28667d2fa8194151d517b761d2cf5 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 14:56:19 -0600 Subject: [PATCH 01/17] saving progress --- library/graphs/dijkstra.hpp | 3 +- library/graphs/hopcroft_karp.hpp | 9 +- .../{knuth_morris_pratt.hpp => kmp.hpp} | 8 +- library/strings/manacher/manacher.hpp | 13 +- library/strings/suffix_array/suffix_array.hpp | 9 +- .../suffix_array/suffix_array_query.hpp | 14 +- .../suffix_array/suffix_array_short.hpp | 9 +- .../string_with_vector.test.cpp | 124 ------------------ tests/scripts/compile_commented_snippets.sh | 5 +- 9 files changed, 40 insertions(+), 154 deletions(-) rename library/strings/{knuth_morris_pratt.hpp => kmp.hpp} (75%) delete mode 100644 tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp diff --git a/library/graphs/dijkstra.hpp b/library/graphs/dijkstra.hpp index f9adfc1f..c7b825d5 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -5,8 +5,7 @@ //! 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 8c26dd9e..748ee0e0 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -12,12 +12,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): - to_r(sz(adj), -1), to_l(rsz, -1) { + hopcroft_karp(const G& adj, int rsz) : to_r(sz(adj), -1), to_l(rsz, -1) { int lsz = sz(adj); while (1) { queue q; @@ -46,7 +45,7 @@ struct hopcroft_karp { for (int u : adj[v]) { int w = to_l[u]; if (w == -1 || - (level[v] + 1 == level[w] && self(self, w))) { + (level[v] + 1 == level[w] && self(self, w))) { to_r[v] = u; to_l[u] = v; return 1; @@ -56,7 +55,7 @@ struct hopcroft_karp { return 0; }; rep(i, 0, lsz) m_sz += - (to_r[i] == -1 && dfs(dfs, i)); + (to_r[i] == -1 && dfs(dfs, i)); } } }; diff --git a/library/strings/knuth_morris_pratt.hpp b/library/strings/kmp.hpp similarity index 75% rename from library/strings/knuth_morris_pratt.hpp rename to library/strings/kmp.hpp index 0ec01063..4963ed67 100644 --- a/library/strings/knuth_morris_pratt.hpp +++ b/library/strings/kmp.hpp @@ -1,17 +1,21 @@ #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 kmp2(t_vec); +//! auto match2 = kmp2.find_str(s_vec); //! @endcode //! if match[i] == 1 then s[i,sz(t)) == t //! @time O(|s| + |t|) //! @space O(|s| + |t|) // NOLINTNEXTLINE(readability-identifier-naming) -template struct KMP { +template struct KMP { T t; vi pi; - KMP(const T& t): t(t), pi(prefix_function(t)) {} + KMP(const T& t) : t(t), pi(prefix_function(t)) {} vector find_str(const T& s) { vector is_m(sz(s)); int j = 0; diff --git a/library/strings/manacher/manacher.hpp b/library/strings/manacher/manacher.hpp index 3df712b2..8164de12 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 -//! auto man = manacher(s); +//! string s6; +//! auto man = manacher(s6); +//! vi s_vec6; +//! auto man2 = manacher(s_vec6); //! @endcode //! //! man[center] = index of start of longest @@ -13,16 +16,16 @@ //! //! @time O(n) //! @space O(n) -template vi manacher(const T& s) { +template vi manacher(const T& s) { int n = sz(s), p = 0; vi man(max(0, 2 * n - 1)); rep(i, 0, 2 * n - 1) { int r = i <= 2 * (p - man[p]) - ? p - max(man[2 * p - i], man[p]) - : i / 2; + ? p - max(man[2 * p - i], man[p]) + : i / 2; man[i] = i - r; while ( - man[i] > 0 && r + 1 < n && s[man[i] - 1] == s[r + 1]) + man[i] > 0 && r + 1 < n && s[man[i] - 1] == s[r + 1]) man[i]--, r++, p = i; } return man; diff --git a/library/strings/suffix_array/suffix_array.hpp b/library/strings/suffix_array/suffix_array.hpp index c42d39fc..6f209460 100644 --- a/library/strings/suffix_array/suffix_array.hpp +++ b/library/strings/suffix_array/suffix_array.hpp @@ -25,14 +25,17 @@ //! lcp = {1, 3, 0, 0, 2} //! //! @code -//! auto [sa, sa_inv, lcp] = get_sa(s, 256); +//! string s1; +//! auto [sa, sa_inv, lcp] = get_sa(s1, 256); +//! vi s_vec1; +//! auto [sa1, sa_inv1, lcp1] = get_sa(s_vec1, 100'001); //! @endcode //! //! requires 0<=s[i] +template array get_sa(const T& s, int max_num) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); @@ -41,7 +44,7 @@ array get_sa(const T& s, int max_num) { vi y(sa_inv), freq(max_num); iota(all(sa_inv), n - i); ranges::copy_if(sa, begin(sa_inv) + i, - [&](int& x) { return (x -= i) >= 0; }); + [&](int& x) { return (x -= i) >= 0; }); for (int x : y) freq[x]++; partial_sum(all(freq), begin(freq)); for (int x : sa_inv | views::reverse) diff --git a/library/strings/suffix_array/suffix_array_query.hpp b/library/strings/suffix_array/suffix_array_query.hpp index 1c862e59..f4bf587e 100644 --- a/library/strings/suffix_array/suffix_array_query.hpp +++ b/library/strings/suffix_array/suffix_array_query.hpp @@ -3,18 +3,20 @@ #include "../../data_structures/rmq.hpp" #include "find/match.hpp" //! @code -//! auto [sa1, sa_inv1, lcp1] = get_sa(s, 256); -//! sa_query saq(s, sa1, sa_inv1, lcp1); +//! string s3; +//! auto [sa4, sa_inv4, lcp4] = get_sa(s3, 256); +//! sa_query saq(s, sa4, sa_inv4, lcp4); +//! vi s_vec3; +//! auto [sa5, sa_inv5, lcp5] = get_sa(s_vec3, 100'001); +//! sa_query saq2(s_vec3, sa5, sa_inv5, lcp5); //! @endcode -template struct sa_query { +template struct sa_query { int n; T s; vi sa, sa_inv, lcp; RMQ> rmq; sa_query(const T& s, const vi& sa, const vi& sa_inv, - const vi& lcp): - n(sz(s)), s(s), sa(sa), sa_inv(sa_inv), lcp(lcp), - rmq(lcp, ranges::min) {} + const vi& lcp) : n(sz(s)), s(s), sa(sa), sa_inv(sa_inv), lcp(lcp), rmq(lcp, ranges::min) {} //! returns max integer k such that //! s.substr(i1, k) == s.substr(i2, k) //! @time O(1) diff --git a/library/strings/suffix_array/suffix_array_short.hpp b/library/strings/suffix_array/suffix_array_short.hpp index 67fb29c8..8c23afd3 100644 --- a/library/strings/suffix_array/suffix_array_short.hpp +++ b/library/strings/suffix_array/suffix_array_short.hpp @@ -2,12 +2,15 @@ //! https://github.com/atcoder/ac-library/blob/master/atcoder/string.hpp //! @code //! // requires s[i]>=0 -//! auto [sa2, sa_inv2, lcp2] = sa_short(s); +//! string s2; +//! auto [sa2, sa_inv2, lcp2] = sa_short(s2); +//! vi s_vec2; +//! auto [sa3, sa_inv3, lcp3] = sa_short(s_vec2); //! @endcode //! runs in ~1.5s for 5e5 //! @time O(n * log^2(n)) //! @space O(n) -template array sa_short(const T& s) { +template array sa_short(const T& s) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); iota(all(sa), 0); @@ -19,7 +22,7 @@ template array sa_short(const T& s) { ranges::sort(sa, {}, proj); sa_inv[sa[0]] = 0; rep(i, 1, n) sa_inv[sa[i]] = - sa_inv[sa[i - 1]] + (proj(sa[i - 1]) != proj(sa[i])); + sa_inv[sa[i - 1]] + (proj(sa[i - 1]) != proj(sa[i])); } int sz = 0; rep(i, 0, n) { 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/scripts/compile_commented_snippets.sh b/tests/scripts/compile_commented_snippets.sh index d1c0db98..87ed906a 100755 --- a/tests/scripts/compile_commented_snippets.sh +++ b/tests/scripts/compile_commented_snippets.sh @@ -17,21 +17,18 @@ git submodule update echo "int main() {" echo "vi a,b,subset;" echo "vl left,bottom,s_vec,t_vec;" - echo "vector adj;" - echo "vector>> adj_w;" echo "vector edges;" echo "vector> eds;" echo "vector> w_eds;" 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,rsz,cols,cap;" } >entire_library_without_main { cat entire_library_without_main - sed --quiet '/\/\/! @code$/,/\/\/! @endcode$/{//!p;}' entire_library_without_main | sed 's/\/\/!//' + sed --quiet '/\/\/! @code$/,/\/\/! @endcode$/p' entire_library_without_main | sed 's/\/\/! @code/{/' | sed 's/\/\/! @endcode/}/' | sed 's/\/\/!//' echo "return 0;" echo "}" } >entire_library.cpp From 3eff9f540b7a24b8a1c73c29ae02e80451013735 Mon Sep 17 00:00:00 2001 From: GitHub Date: Sat, 14 Dec 2024 21:18:30 +0000 Subject: [PATCH 02/17] [auto-verifier] verify commit 31974eeca9d28667d2fa8194151d517b761d2cf5 --- .verify-helper/timestamps.remote.json | 36 +++++++++++++-------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/.verify-helper/timestamps.remote.json b/.verify-helper/timestamps.remote.json index 825f956b..bdb2edbb 100644 --- a/.verify-helper/timestamps.remote.json +++ b/.verify-helper/timestamps.remote.json @@ -51,12 +51,12 @@ "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-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/graphs/connected_components_of_complement_graph.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/graphs/dijkstra_aizu.test.cpp": "2024-11-17 14:04:03 -0600", -"tests/library_checker_aizu_tests/graphs/dijkstra_lib_checker.test.cpp": "2024-11-17 14:04:03 -0600", +"tests/library_checker_aizu_tests/graphs/dijkstra_aizu.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/graphs/dijkstra_lib_checker.test.cpp": "2024-12-14 14:56:19 -0600", "tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp": "2024-11-17 14:04:03 -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-11-19 11:51:33 -0600", -"tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2024-11-19 11:51:33 -0600", +"tests/library_checker_aizu_tests/graphs/hopcroft_karp_aizu.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/graphs/hopcroft_karp_lib_checker.test.cpp": "2024-12-14 14:56:19 -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-11-17 14:04:03 -0600", "tests/library_checker_aizu_tests/graphs/strongly_connected_components_aizu.test.cpp": "2024-11-17 14:04:03 -0600", @@ -69,17 +69,16 @@ "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-05 10:41:42 -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/manacher.test.cpp": "2024-12-14 14:56:19 -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-05 10:41:42 -0600", "tests/library_checker_aizu_tests/handmade_tests/rmq_small_n.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/handmade_tests/sa_find_subarray.test.cpp": "2024-12-08 12:47:08 -0600", +"tests/library_checker_aizu_tests/handmade_tests/sa_find_subarray.test.cpp": "2024-12-14 14:56:19 -0600", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find.test.cpp": "2024-12-05 10:41:42 -0600", "tests/library_checker_aizu_tests/handmade_tests/seg_tree_find_small.test.cpp": "2024-12-05 10:41:42 -0600", -"tests/library_checker_aizu_tests/handmade_tests/string_with_vector.test.cpp": "2024-12-08 12:47:08 -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", @@ -107,22 +106,21 @@ "tests/library_checker_aizu_tests/monotonic_stack_related/cartesian_k_ary_tree.test.cpp": "2024-12-05 10:41:42 -0600", "tests/library_checker_aizu_tests/monotonic_stack_related/count_rectangles.test.cpp": "2024-12-05 10:41:42 -0600", "tests/library_checker_aizu_tests/monotonic_stack_related/max_rect_histogram.test.cpp": "2024-12-05 10:41:42 -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-11-22 12:15:07 -0600", -"tests/library_checker_aizu_tests/strings/lcp_query_palindrome.test.cpp": "2024-12-08 12:47:08 -0600", -"tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp": "2024-12-08 12:47:08 -0600", +"tests/library_checker_aizu_tests/strings/lcp_array.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/lcp_query_palindrome.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp": "2024-12-14 14:56:19 -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-08 12:47:08 -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-08 12:47:08 -0600", +"tests/library_checker_aizu_tests/strings/longest_common_substring.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/manacher.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/multi_matching_bs.test.cpp": "2024-12-14 14:56:19 -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-08 12:47:08 -0600", -"tests/library_checker_aizu_tests/strings/sa_sort_pairs.test.cpp": "2024-12-08 12:47:08 -0600", -"tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp": "2024-12-08 12:47:08 -0600", -"tests/library_checker_aizu_tests/strings/suffix_array.test.cpp": "2024-12-08 12:47:08 -0600", -"tests/library_checker_aizu_tests/strings/suffix_array_short.test.cpp": "2024-11-22 12:15:07 -0600", +"tests/library_checker_aizu_tests/strings/sa_cmp.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/sa_sort_pairs.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/suffix_array.test.cpp": "2024-12-14 14:56:19 -0600", +"tests/library_checker_aizu_tests/strings/suffix_array_short.test.cpp": "2024-12-14 14:56:19 -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-05 10:41:42 -0600", From b9b1dbcfca71b9b0cef2f618d3449c08d2672f7b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:12:53 -0600 Subject: [PATCH 03/17] changes --- library/graphs/dijkstra.hpp | 3 ++- library/graphs/hopcroft_karp.hpp | 9 +++++---- library/strings/kmp.hpp | 8 ++++---- .../longest_common_subsequence/lcs_queries.hpp | 12 ++++++++++-- library/strings/manacher/manacher.hpp | 18 +++++++++--------- library/strings/suffix_array/suffix_array.hpp | 15 +++++++-------- .../suffix_array/suffix_array_query.hpp | 8 +++++--- .../suffix_array/suffix_array_short.hpp | 11 ++--------- 8 files changed, 44 insertions(+), 40 deletions(-) diff --git a/library/graphs/dijkstra.hpp b/library/graphs/dijkstra.hpp index 5c931684..a59dadb7 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -6,7 +6,8 @@ //! d[v] = min dist from source->..->v //! @time O(n + (m log m)) //! @space O(n + m) -template vector dijkstra(const G& 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 d548111b..22d22316 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -13,11 +13,12 @@ //! mvc_r[r] is 1 if r in Min Vertex Cover //! @time O(n + m * sqrt(n)) n = lsz + rsz //! @space O(n) -template struct hopcroft_karp { +template struct hopcroft_karp { int m_sz = 0; vi to_r, to_l; vector mvc_l, mvc_r; - hopcroft_karp(const G& adj, int rsz) : to_r(sz(adj), -1), to_l(rsz, -1) { + hopcroft_karp(const G& adj, int rsz): + to_r(sz(adj), -1), to_l(rsz, -1) { int lsz = sz(adj); while (1) { queue q; @@ -46,7 +47,7 @@ template struct hopcroft_karp { for (int u : adj[v]) { int w = to_l[u]; if (w == -1 || - (level[v] + 1 == level[w] && self(self, w))) { + (level[v] + 1 == level[w] && self(self, w))) { to_r[v] = u; to_l[u] = v; return 1; @@ -56,7 +57,7 @@ template struct hopcroft_karp { return 0; }; rep(i, 0, lsz) m_sz += - (to_r[i] == -1 && dfs(dfs, i)); + (to_r[i] == -1 && dfs(dfs, i)); } } }; diff --git a/library/strings/kmp.hpp b/library/strings/kmp.hpp index 4963ed67..c691faae 100644 --- a/library/strings/kmp.hpp +++ b/library/strings/kmp.hpp @@ -5,17 +5,17 @@ //! KMP kmp(t); //! auto match = kmp.find_str(s); //! vi s_vec,t_vec; -//! KMP kmp2(t_vec); -//! auto match2 = kmp2.find_str(s_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|) //! @space O(|s| + |t|) // NOLINTNEXTLINE(readability-identifier-naming) -template struct KMP { +template struct KMP { T t; vi pi; - KMP(const T& t) : t(t), pi(prefix_function(t)) {} + KMP(const T& t): t(t), pi(prefix_function(t)) {} vector find_str(const T& s) { vector is_m(sz(s)); int j = 0; 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 8164de12..566b0593 100644 --- a/library/strings/manacher/manacher.hpp +++ b/library/strings/manacher/manacher.hpp @@ -1,10 +1,10 @@ #pragma once //! https://codeforces.com/blog/entry/12143#comment-324162 //! @code -//! string s6; -//! auto man = manacher(s6); -//! vi s_vec6; -//! auto man2 = manacher(s_vec6); +//! string s; +//! auto man = manacher(s); +//! vi s_vec; +//! auto man1 = manacher(s_vec); //! @endcode //! //! man[center] = index of start of longest @@ -16,16 +16,16 @@ //! //! @time O(n) //! @space O(n) -template vi manacher(const T& s) { +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]) - : i / 2; + ? p - max(man[2 * p - i], man[p]) + : i / 2; man[i] = i - r; while ( - man[i] > 0 && r + 1 < n && s[man[i] - 1] == s[r + 1]) + man[i] > 0 && r + 1 < n && s[man[i] - 1] == s[r + 1]) man[i]--, r++, p = i; } return man; diff --git a/library/strings/suffix_array/suffix_array.hpp b/library/strings/suffix_array/suffix_array.hpp index 6f209460..27ff90be 100644 --- a/library/strings/suffix_array/suffix_array.hpp +++ b/library/strings/suffix_array/suffix_array.hpp @@ -25,17 +25,16 @@ //! lcp = {1, 3, 0, 0, 2} //! //! @code -//! string s1; -//! auto [sa, sa_inv, lcp] = get_sa(s1, 256); -//! vi s_vec1; -//! auto [sa1, sa_inv1, lcp1] = get_sa(s_vec1, 100'001); +//! // requires 0<=s[i] +template array get_sa(const T& s, int max_num) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); @@ -44,7 +43,7 @@ array get_sa(const T& s, int max_num) { vi y(sa_inv), freq(max_num); iota(all(sa_inv), n - i); ranges::copy_if(sa, begin(sa_inv) + i, - [&](int& x) { return (x -= i) >= 0; }); + [&](int& x) { return (x -= i) >= 0; }); for (int x : y) freq[x]++; partial_sum(all(freq), begin(freq)); for (int x : sa_inv | views::reverse) diff --git a/library/strings/suffix_array/suffix_array_query.hpp b/library/strings/suffix_array/suffix_array_query.hpp index 4e54a332..4d242f44 100644 --- a/library/strings/suffix_array/suffix_array_query.hpp +++ b/library/strings/suffix_array/suffix_array_query.hpp @@ -8,15 +8,17 @@ //! sa_query saq(s, sa, sa_inv, lcp); //! vi s_vec; //! auto [sa1, sa_inv1, lcp1] = sa_short(s_vec, 100'001); -//! sa_query saq(s_vec, sa1, sa_inv1, lcp1); +//! sa_query saq1(s_vec, sa1, sa_inv1, lcp1); //! @endcode -template struct sa_query { +template struct sa_query { int n; T s; vi sa, sa_inv, lcp; RMQ> rmq; sa_query(const T& s, const vi& sa, const vi& sa_inv, - const vi& lcp) : n(sz(s)), s(s), sa(sa), sa_inv(sa_inv), lcp(lcp), rmq(lcp, ranges::min) {} + const vi& lcp): + n(sz(s)), s(s), sa(sa), sa_inv(sa_inv), lcp(lcp), + rmq(lcp, ranges::min) {} //! returns max integer k such that //! s.substr(i1, k) == s.substr(i2, k) //! @time O(1) diff --git a/library/strings/suffix_array/suffix_array_short.hpp b/library/strings/suffix_array/suffix_array_short.hpp index 6b8bb0d5..65c6044c 100644 --- a/library/strings/suffix_array/suffix_array_short.hpp +++ b/library/strings/suffix_array/suffix_array_short.hpp @@ -2,22 +2,15 @@ //! https://github.com/atcoder/ac-library/blob/master/atcoder/string.hpp //! @code //! // requires s[i]>=0 -<<<<<<< HEAD -//! string s2; -//! auto [sa2, sa_inv2, lcp2] = sa_short(s2); -//! vi s_vec2; -//! auto [sa3, sa_inv3, lcp3] = sa_short(s_vec2); -======= //! string s; //! auto [sa, sa_inv, lcp] = sa_short(s); //! vi s_vec; //! auto [sa1, sa_inv1, lcp1] = sa_short(s_vec); ->>>>>>> dev //! @endcode //! runs in ~1.5s for 5e5 //! @time O(n * log^2(n)) //! @space O(n) -template array sa_short(const T& s) { +template array sa_short(const T& s) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); iota(all(sa), 0); @@ -29,7 +22,7 @@ template array sa_short(const T& s) { ranges::sort(sa, {}, proj); sa_inv[sa[0]] = 0; rep(i, 1, n) sa_inv[sa[i]] = - sa_inv[sa[i - 1]] + (proj(sa[i - 1]) != proj(sa[i])); + sa_inv[sa[i - 1]] + (proj(sa[i - 1]) != proj(sa[i])); } int sz = 0; rep(i, 0, n) { From 7f857c9060f6b184f91ceab1e8f2ca318cda7b7e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:15:38 -0600 Subject: [PATCH 04/17] a fix --- tests/scripts/compile_commented_snippets.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/scripts/compile_commented_snippets.sh b/tests/scripts/compile_commented_snippets.sh index 819f350c..17ba92e5 100755 --- a/tests/scripts/compile_commented_snippets.sh +++ b/tests/scripts/compile_commented_snippets.sh @@ -21,7 +21,7 @@ git submodule update 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;" From 1536695789dafe723d2df3eb2b9865bef8fa0b4d Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:16:12 -0600 Subject: [PATCH 05/17] fix compile error --- tests/library_checker_aizu_tests/strings/kmp.test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From cec43fd12ac2725467b2ee581e9cded7d56df93e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:21:36 -0600 Subject: [PATCH 06/17] fix --- library/strings/suffix_array/suffix_array_query.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/strings/suffix_array/suffix_array_query.hpp b/library/strings/suffix_array/suffix_array_query.hpp index 4d242f44..8444b010 100644 --- a/library/strings/suffix_array/suffix_array_query.hpp +++ b/library/strings/suffix_array/suffix_array_query.hpp @@ -7,7 +7,7 @@ //! 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, 100'001); +//! auto [sa1, sa_inv1, lcp1] = sa_short(s_vec); //! sa_query saq1(s_vec, sa1, sa_inv1, lcp1); //! @endcode template struct sa_query { From 09b235f22c971c45dfc96190c18c66ecfa2532a5 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:25:21 -0600 Subject: [PATCH 07/17] more fixes --- library/strings/suffix_array/compare/compare_substrings.hpp | 1 + library/strings/suffix_array/compare/compare_suffixes.hpp | 1 + library/strings/suffix_array/find/find_substring.hpp | 1 + library/strings/wildcard_pattern_matching.hpp | 1 + library/trees/tree_lift/tree_lift.hpp | 1 + 5 files changed, 5 insertions(+) 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/wildcard_pattern_matching.hpp b/library/strings/wildcard_pattern_matching.hpp index d69a5243..e85410be 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 +//! vi s_vec, t_vec; //! auto mtch = wildcard_pattern_matching( //! s_vec, t_vec, conv); //! @endcode diff --git a/library/trees/tree_lift/tree_lift.hpp b/library/trees/tree_lift/tree_lift.hpp index f88a3bbf..c8c34ea6 100644 --- a/library/trees/tree_lift/tree_lift.hpp +++ b/library/trees/tree_lift/tree_lift.hpp @@ -1,6 +1,7 @@ #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); //! @endcode From 6c728a9d02adfd82b780c69e796b7ccb273ab808 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:28:30 -0600 Subject: [PATCH 08/17] final fix --- library/strings/wildcard_pattern_matching.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/strings/wildcard_pattern_matching.hpp b/library/strings/wildcard_pattern_matching.hpp index e85410be..01a06727 100644 --- a/library/strings/wildcard_pattern_matching.hpp +++ b/library/strings/wildcard_pattern_matching.hpp @@ -1,7 +1,7 @@ #pragma once //! https://codeforces.com/blog/entry/111380 //! @code -//! vi s_vec, t_vec; +//! vl s_vec, t_vec; //! auto mtch = wildcard_pattern_matching( //! s_vec, t_vec, conv); //! @endcode From c2a18e35fa5e5953fb2f2d00b362c1c3a2a4e794 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:30:29 -0600 Subject: [PATCH 09/17] remove old readme --- tests/library_checker_aizu_tests/strings/README.md | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tests/library_checker_aizu_tests/strings/README.md 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). From 46dabce7fade6dd87797cb0dc3711d5d3a0c5a18 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:48:32 -0600 Subject: [PATCH 10/17] add templatized versions of graphs --- library/graphs/bridges_cuts/block_vertex_tree.hpp | 8 ++++++-- library/graphs/bridges_cuts/bridge_tree.hpp | 3 +++ library/graphs/bridges_cuts/bridges.hpp | 7 +++++-- library/graphs/bridges_cuts/cuts.hpp | 6 ++++-- library/graphs/complement_graph_ccs.hpp | 7 +++++-- library/graphs/dijkstra.hpp | 2 ++ library/graphs/hopcroft_karp.hpp | 2 ++ library/graphs/strongly_connected_components/scc.hpp | 2 ++ library/trees/centroid_decomp.hpp | 10 +++++++--- library/trees/edge_cd.hpp | 10 +++++++--- library/trees/ladder_decomposition/linear_kth_par.hpp | 8 +++++--- library/trees/lca_rmq/lca_rmq.hpp | 6 ++++-- library/trees/subtree_isomorphism.hpp | 6 ++++-- library/trees/tree_lift/tree_lift.hpp | 6 ++++-- 14 files changed, 60 insertions(+), 23 deletions(-) diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index 66043a60..f0d1a64a 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..bf61ddac 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -4,6 +4,9 @@ //! 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) 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 a59dadb7..e728c021 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -2,6 +2,8 @@ //! @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)) diff --git a/library/graphs/hopcroft_karp.hpp b/library/graphs/hopcroft_karp.hpp index 22d22316..8174d79f 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); //! @endcode //! 0<=l to_r[l] in matching if to_r[l]!=-1 diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 75baecd3..3f015922 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -3,6 +3,8 @@ //! @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] 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..b839f481 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 { + G adj; F f; vi sub_sz; - edge_cd(const vector& adj, F f): + edge_cd(const G& adj, F f): adj(adj), f(f), sub_sz(sz(adj)) { dfs(0, sz(adj)); } 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/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 c8c34ea6..7fe4efd1 100644 --- a/library/trees/tree_lift/tree_lift.hpp +++ b/library/trees/tree_lift/tree_lift.hpp @@ -4,16 +4,18 @@ //! 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) From 284f444fc3c15502309a9fba6d2e2fa49286b2f3 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 16:52:38 -0600 Subject: [PATCH 11/17] some more fixes --- library/graphs/bridges_cuts/block_vertex_tree.hpp | 2 +- library/graphs/bridges_cuts/bridge_tree.hpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index f0d1a64a..a119ba72 100644 --- a/library/graphs/bridges_cuts/block_vertex_tree.hpp +++ b/library/graphs/bridges_cuts/block_vertex_tree.hpp @@ -20,7 +20,7 @@ //! @time O(n) template vector block_vertex_tree(const G& adj, - const cuts& cc) { + 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 bf61ddac..9b797a16 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -10,8 +10,9 @@ //! @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]] From 7bdfc784f9886504db70704fe21d67e583809a27 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:02:21 -0600 Subject: [PATCH 12/17] final fix --- library/trees/edge_cd.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/trees/edge_cd.hpp b/library/trees/edge_cd.hpp index b839f481..c759d302 100644 --- a/library/trees/edge_cd.hpp +++ b/library/trees/edge_cd.hpp @@ -20,10 +20,10 @@ //! @time O(n log1.5 n) //! @space O(n) template struct edge_cd { - G adj; + vector adj; F f; vi sub_sz; - edge_cd(const G& adj, F f): + edge_cd(const vector& adj, F f): adj(adj), f(f), sub_sz(sz(adj)) { dfs(0, sz(adj)); } @@ -44,14 +44,14 @@ template struct edge_cd { if (siz <= 2) return; v = find_cent(v, -1, siz); int sum = 0; - auto it = partition(all(adj[v]), [&](int u) { + auto it = ranges::partition(adj[v], [&](int u) { bool ret = 2 * sum + sub_sz[u] < siz - 1 && 3 * (sum + sub_sz[u]) <= 2 * (siz - 1); if (ret) sum += sub_sz[u]; 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); From 40a6294391421f5e9d1c12fc63ed4fa1b07491ad Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:07:29 -0600 Subject: [PATCH 13/17] more fixes --- library/trees/linear_kth_path.hpp | 8 ++++---- library/trees/linear_lca.hpp | 11 ++++++++--- .../compress_tree_asserts.hpp | 2 +- .../trees/kth_node_on_path.test.cpp | 3 +-- 4 files changed, 14 insertions(+), 10 deletions(-) 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/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/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; From 5d7769619248be36a4b5bcf5a2da9d18d8c5258e Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:11:09 -0600 Subject: [PATCH 14/17] actually let's not use this --- library/trees/edge_cd.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/trees/edge_cd.hpp b/library/trees/edge_cd.hpp index c759d302..85f6dbc1 100644 --- a/library/trees/edge_cd.hpp +++ b/library/trees/edge_cd.hpp @@ -44,7 +44,7 @@ template struct edge_cd { if (siz <= 2) return; v = find_cent(v, -1, siz); int sum = 0; - auto it = ranges::partition(adj[v], [&](int u) { + auto it = partition(all(adj[v]), [&](int u) { bool ret = 2 * sum + sub_sz[u] < siz - 1 && 3 * (sum + sub_sz[u]) <= 2 * (siz - 1); if (ret) sum += sub_sz[u]; From 044394f2ec3ecfcbda52c2dccf8e038cee8fcfb8 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:14:37 -0600 Subject: [PATCH 15/17] final fixes --- library/graphs/hopcroft_karp.hpp | 2 +- library/graphs/strongly_connected_components/scc.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/graphs/hopcroft_karp.hpp b/library/graphs/hopcroft_karp.hpp index 8174d79f..8c7cdd68 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -6,7 +6,7 @@ //! auto [matching_size, to_r, to_l, //! mvc_l, mvc_r] = hopcroft_karp(adj, rsz); //! vector> adj1(lsz); -//! hopcroft_karp match(adj1); +//! hopcroft_karp match(adj1, rsz); //! @endcode //! 0<=l to_r[l] in matching if to_r[l]!=-1 diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 3f015922..d658eb5f 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -10,10 +10,10 @@ //! for each edge u -> 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 { From f9f0d32739a14b75b31a35a7eb9a3d3acf80760b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:19:51 -0600 Subject: [PATCH 16/17] some fixes --- tests/.config/.cppcheck_suppression_list | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index 7a1986b8..c8a8e53f 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,6 @@ 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 From c447bdb726fe3635fb6030dd31f1ae711cba87eb Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:21:53 -0600 Subject: [PATCH 17/17] supress --- tests/.config/.cppcheck_suppression_list | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index c8a8e53f..e20e98ca 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -54,3 +54,4 @@ constVariable:../kactl/content/graph/CompressTree.h:20 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