From 73e5617a43a68e763f3288ecbce0e1336a5faeb6 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 17:46:31 -0600 Subject: [PATCH 01/16] golf --- .../offline_incremental_scc.hpp | 2 +- .../strongly_connected_components/scc.hpp | 41 +++++++++---------- .../scc_asserts.hpp | 3 +- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/library/graphs/strongly_connected_components/offline_incremental_scc.hpp b/library/graphs/strongly_connected_components/offline_incremental_scc.hpp index 7c2748cc..2feedbb7 100644 --- a/library/graphs/strongly_connected_components/offline_incremental_scc.hpp +++ b/library/graphs/strongly_connected_components/offline_incremental_scc.hpp @@ -32,7 +32,7 @@ vi offline_incremental_scc(vector> eds, if (*it <= mid) adj[u].push_back(v); } for (int v : vs) ids[v] = -1; - auto scc_id = sccs(adj).scc_id; + auto scc_id = sccs(adj).second; auto split = partition(el, er, [&](int i) { return scc_id[eds[i][0]] == scc_id[eds[i][1]]; }); diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index d658eb5f..f1e32c98 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -10,25 +10,22 @@ //! for each edge u -> v: scc_id[u] >= scc_id[v] //! @time O(n + m) //! @space O(n) -template struct sccs { - int num_sccs = 0; - vi scc_id; - 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 { - int low = tin[v] = timer++, siz = sz(st); - st.push_back(v); - for (int u : adj[v]) - if (scc_id[u] < 0) - low = min(low, tin[u] ? tin[u] : self(self, u)); - if (tin[v] == low) { - rep(i, siz, sz(st)) scc_id[st[i]] = num_sccs; - st.resize(siz); - num_sccs++; - } - return low; - }; - rep(i, 0, n) if (!tin[i]) dfs(dfs, i); - } -}; +template pair sccs(const G& adj) { + int n = sz(adj), num_sccs = 0, timer = 0; + vi scc_id(n, -1), tin(n), st; + auto dfs = [&](auto&& self, int v) -> int { + int low = tin[v] = ++timer, siz = sz(st); + st.push_back(v); + for (int u : adj[v]) + if (scc_id[u] < 0) + low = min(low, tin[u] ?: self(self, u)); + if (tin[v] == low) { + rep(i, siz, sz(st)) scc_id[st[i]] = num_sccs; + st.resize(siz); + num_sccs++; + } + return low; + }; + rep(i, 0, n) if (!tin[i]) dfs(dfs, i); + return {num_sccs, scc_id}; +} diff --git a/tests/library_checker_aizu_tests/scc_asserts.hpp b/tests/library_checker_aizu_tests/scc_asserts.hpp index 6df395a3..48edbaae 100644 --- a/tests/library_checker_aizu_tests/scc_asserts.hpp +++ b/tests/library_checker_aizu_tests/scc_asserts.hpp @@ -34,6 +34,5 @@ void scc_asserts(const vector>& adj) { assert(u != v); adj_copy[u].push_back(v); } - sccs curr_res(adj_copy); - assert(curr_res.num_sccs == 1); + assert(sccs(adj_copy).first == 1); } From ce4aff32ca211d4bd52722ce9fc751eee67b5cab Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:01:57 -0600 Subject: [PATCH 02/16] update bridges --- library/graphs/bridges_cuts/bridge_tree.hpp | 10 ++-- library/graphs/bridges_cuts/bridges.hpp | 49 +++++++++---------- .../graphs/two_edge_components.test.cpp | 32 ++++++------ 3 files changed, 43 insertions(+), 48 deletions(-) diff --git a/library/graphs/bridges_cuts/bridge_tree.hpp b/library/graphs/bridges_cuts/bridge_tree.hpp index 9b797a16..53794ebf 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -11,11 +11,11 @@ //! @time O(n + m) //! @space O(n) template -vector bridge_tree(const G& adj, - const bridges& br) { - vector tree(br.num_ccs); +vector bridge_tree(const G& adj, int num_ccs, + const vi& br_id, const vi& is_br) { + vector tree(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]] - .push_back(br.br_id[u]); + is_br[e_id]) tree[br_id[i]] + .push_back(br_id[u]); return tree; } diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index 80f075ed..baa4d5a1 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -9,39 +9,36 @@ //! adj[u].emplace_back(v, i); //! adj[v].emplace_back(u, i); //! } -//! auto [num_ccs, is_bridge, br_id] = bridges(adj, m); +//! auto [num_ccs, is_br, 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 +//! is_br[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 G& adj, int m): - is_bridge(m), br_id(sz(adj), -1) { - int n = sz(adj), timer = 1; - vi tin(n), st; - auto dfs = [&](auto&& self, int v, int p_id) -> int { - int low = tin[v] = timer++, siz = sz(st); - st.push_back(v); - for (auto [u, e_id] : adj[v]) { - if (e_id == p_id) continue; +template +tuple bridges(const G& adj, int m) { + int n = sz(adj), num_ccs = 0, timer = 0; + vi br_id(n, -1), is_br(m), tin(n), st; + auto dfs = [&](auto&& self, int v, int p_id) -> int { + int low = tin[v] = ++timer, siz = sz(st); + st.push_back(v); + for (auto [u, e_id] : adj[v]) + if (e_id != p_id) { + // TODO golf this if (!tin[u]) low = min(low, self(self, u, e_id)); low = min(low, tin[u]); } - if (tin[v] == low) { - if (p_id != -1) is_bridge[p_id] = 1; - rep(i, siz, sz(st)) br_id[st[i]] = num_ccs; - st.resize(siz); - num_ccs++; - } - return low; - }; - rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); - } -}; + if (tin[v] == low) { + if (p_id != -1) is_br[p_id] = 1; + rep(i, siz, sz(st)) br_id[st[i]] = num_ccs; + st.resize(siz); + num_ccs++; + } + return low; + }; + rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); + return {num_ccs, br_id, is_br}; +} diff --git a/tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp b/tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp index fb5dbc09..1ab0e485 100644 --- a/tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp +++ b/tests/library_checker_aizu_tests/graphs/two_edge_components.test.cpp @@ -16,35 +16,35 @@ int main() { adj[v].emplace_back(u, i); edges[i] = {u, v}; } - bridges br(adj, m); - vector> bt = bridge_tree(adj, br); - assert(find(begin(br.br_id), end(br.br_id), -1) == - end(br.br_id)); + auto [num_ccs, br_id, is_br] = bridges(adj, m); + vector> bt = + bridge_tree(adj, num_ccs, br_id, is_br); + assert(find(begin(br_id), end(br_id), -1) == end(br_id)); // check correctness of bridge tree { - assert(sz(bt) == br.num_ccs); - for (int v = 0; v < br.num_ccs; v++) + assert(sz(bt) == num_ccs); + for (int v = 0; v < num_ccs; v++) for (auto to : bt[v]) assert(to != v); // didn't add any non-bridge int sum_deg = accumulate(begin(bt), end(bt), 0, [](int sum, const auto& neighbors) -> int { return sum + sz(neighbors); }); - int cnt_bridges = accumulate(begin(br.is_bridge), - end(br.is_bridge), 0); + int cnt_bridges = + accumulate(begin(is_br), end(is_br), 0); assert(sum_deg % 2 == 0 && sum_deg / 2 == cnt_bridges); } dsu_restorable dsu(n); int num_sets_dsu = n; for (int i = 0; i < m; i++) { - if (!br.is_bridge[i]) { + if (!is_br[i]) { auto [u, v] = edges[i]; num_sets_dsu -= dsu.join(u, v); } } assert(num_sets_dsu == sz(bt)); for (int i = 0; i < m; i++) { - if (br.is_bridge[i]) { + if (is_br[i]) { auto [u, v] = edges[i]; bool same_set = dsu.same_set(u, v); assert(!same_set); @@ -52,18 +52,16 @@ int main() { } for (int i = 0; i < n; i++) { int par_of_cc = dsu.find(i); - assert(br.br_id[i] == br.br_id[par_of_cc]); + assert(br_id[i] == br_id[par_of_cc]); } for (int i = 0; i < m; i++) { auto [u, v] = edges[i]; // bridge if nodes are from different 2-edge CCs - assert( - br.is_bridge[i] == (br.br_id[u] != br.br_id[v])); + assert(is_br[i] == (br_id[u] != br_id[v])); } - vector> ccs(br.num_ccs); - for (int i = 0; i < n; i++) - ccs[br.br_id[i]].push_back(i); - cout << br.num_ccs << '\n'; + vector> ccs(num_ccs); + for (int i = 0; i < n; i++) ccs[br_id[i]].push_back(i); + cout << num_ccs << '\n'; for (const auto& curr_cc : ccs) { cout << sz(curr_cc) << " "; for (auto node : curr_cc) cout << node << " "; From 3b6e828de4b6c25d7036c643a7a8ef55755cfcbd Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:06:20 -0600 Subject: [PATCH 03/16] golf bridges now --- library/graphs/bridges_cuts/bridges.hpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index baa4d5a1..ae66ee14 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -9,9 +9,7 @@ //! adj[u].emplace_back(v, i); //! adj[v].emplace_back(u, i); //! } -//! auto [num_ccs, is_br, br_id] = bridges(adj, m); //! vector>> adj1(n); -//! auto [num_ccs1, is_bridge1, br_id1] = bridges(adj1, //! m); //! @endcode //! is_br[edge id] = 1 iff bridge edge @@ -26,11 +24,8 @@ tuple bridges(const G& adj, int m) { int low = tin[v] = ++timer, siz = sz(st); st.push_back(v); for (auto [u, e_id] : adj[v]) - if (e_id != p_id) { - // TODO golf this - if (!tin[u]) low = min(low, self(self, u, e_id)); - low = min(low, tin[u]); - } + if (e_id != p_id && br_id[u] < 0) + low = min(low, tin[u] ?: self(self, u, e_id)); if (tin[v] == low) { if (p_id != -1) is_br[p_id] = 1; rep(i, siz, sz(st)) br_id[st[i]] = num_ccs; From d617a7a7bd38488954623be7684872a0d67867b7 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:30:57 -0600 Subject: [PATCH 04/16] convert this now --- .../graphs/bridges_cuts/block_vertex_tree.hpp | 10 +-- library/graphs/bridges_cuts/cuts.hpp | 64 +++++++++---------- .../graphs/biconnected_components.test.cpp | 31 ++++----- 3 files changed, 51 insertions(+), 54 deletions(-) diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index a119ba72..8085fc0d 100644 --- a/library/graphs/bridges_cuts/block_vertex_tree.hpp +++ b/library/graphs/bridges_cuts/block_vertex_tree.hpp @@ -19,14 +19,14 @@ //! @time O(n + m) //! @time O(n) template -vector block_vertex_tree(const G& adj, - const cuts& cc) { +vector block_vertex_tree(const G& adj, int num_bccs, + const vi& bcc_id) { int n = sz(adj); - vector bvt(n + cc.num_bccs); - vector vis(cc.num_bccs); + vector bvt(n + num_bccs); + vector vis(num_bccs); rep(i, 0, n) { for (auto [_, e_id] : adj[i]) { - int bccid = cc.bcc_id[e_id]; + int bccid = bcc_id[e_id]; if (!vis[bccid]) { vis[bccid] = 1; bvt[i].push_back(bccid + n); diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index 9d4717eb..469e2fad 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -18,39 +18,35 @@ //! bcc_id[edge id] = id, 0<=id struct cuts { - int num_bccs = 0; - vector is_cut; - vi bcc_id; - cuts(const G& adj, int m): - is_cut(sz(adj)), bcc_id(m, -1) { - int n = sz(adj), timer = 1; - vi tin(n), st; - auto dfs = [&](auto&& self, int v, int p_id) -> int { - int low = tin[v] = timer++, deg = 0; - for (auto [u, e_id] : adj[v]) { - assert(v != u); - if (e_id == p_id) continue; - if (!tin[u]) { - int siz = sz(st); - st.push_back(e_id); - int low_ch = self(self, u, e_id); - if (low_ch >= tin[v]) { - is_cut[v] = 1; - rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs; - st.resize(siz); - num_bccs++; - } - low = min(low, low_ch); - deg++; - } else if (tin[u] < tin[v]) { - st.push_back(e_id); - low = min(low, tin[u]); +template +tuple cuts(const G& adj, int m) { + int n = sz(adj), num_bccs = 0, timer = 0; + vi bcc_id(m, -1), is_cut(n), tin(n), st; + auto dfs = [&](auto&& self, int v, int p_id) -> int { + int low = tin[v] = ++timer, deg = 0; + for (auto [u, e_id] : adj[v]) { + assert(v != u); + if (e_id == p_id) continue; + if (!tin[u]) { + int siz = sz(st); + st.push_back(e_id); + int low_ch = self(self, u, e_id); + if (low_ch >= tin[v]) { + is_cut[v] = 1; + rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs; + st.resize(siz); + num_bccs++; } + low = min(low, low_ch); + deg++; + } else if (tin[u] < tin[v]) { + st.push_back(e_id); + low = min(low, tin[u]); } - if (p_id == -1) is_cut[v] = (deg > 1); - return low; - }; - rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); - } -}; + } + if (p_id == -1) is_cut[v] = (deg > 1); + return low; + }; + rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); + return {num_bccs, bcc_id, is_cut}; +} diff --git a/tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp b/tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp index 54692c34..f6449190 100644 --- a/tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp +++ b/tests/library_checker_aizu_tests/graphs/biconnected_components.test.cpp @@ -15,34 +15,35 @@ int main() { adj[v].emplace_back(u, i); edges[i] = make_pair(u, v); } - cuts cc(adj, m); - vector> bvt = block_vertex_tree(adj, cc); - assert(find(begin(cc.bcc_id), end(cc.bcc_id), -1) == - end(cc.bcc_id)); + auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); + vector> bvt = + block_vertex_tree(adj, num_bccs, bcc_id); + assert( + find(begin(bcc_id), end(bcc_id), -1) == end(bcc_id)); for (int i = 0; i < n; i++) { // cut node if there exists a pair of adjacent edges // belonging to different BCCs - bool is_cut = 0; + bool curr_is_cut = 0; for (int j = 0; j < sz(adj[i]); j++) - if (cc.bcc_id[adj[i][0].second] != - cc.bcc_id[adj[i][j].second]) - is_cut = 1; - assert(is_cut == cc.is_cut[i]); + if (bcc_id[adj[i][0].second] != + bcc_id[adj[i][j].second]) + curr_is_cut = 1; + assert(curr_is_cut == is_cut[i]); } // check correctness of block vertex tree for (int i = 0; i < n; i++) { assert(sz(adj[i]) >= sz(bvt[i])); // in particular, if empty(adj[i]), then // empty(bct[i]) - assert(cc.is_cut[i] == + assert(is_cut[i] == (sz(bvt[i]) > 1)); // is cut means non-leaf in block vertex tree } { - vector> bcc_to_nodes(cc.num_bccs), + vector> bcc_to_nodes(num_bccs), node_to_bccs(n); for (int i = 0; i < m; i++) { - int bccid = cc.bcc_id[i]; + int bccid = bcc_id[i]; for (auto node : {edges[i].first, edges[i].second}) { bcc_to_nodes[bccid].insert(node); node_to_bccs[node].insert(bccid); @@ -56,7 +57,7 @@ int main() { assert(node_to_bccs[u].contains(bccid)); } } - for (int bccid = 0; bccid < cc.num_bccs; bccid++) { + for (int bccid = 0; bccid < num_bccs; bccid++) { assert( sz(bcc_to_nodes[bccid]) == sz(bvt[bccid + n])); for (auto u : bvt[bccid + n]) @@ -66,8 +67,8 @@ int main() { vector lone_nodes; for (int u = 0; u < n; u++) if (empty(bvt[u])) lone_nodes.push_back(u); - cout << cc.num_bccs + sz(lone_nodes) << '\n'; - for (int bccid = 0; bccid < cc.num_bccs; bccid++) { + cout << num_bccs + sz(lone_nodes) << '\n'; + for (int bccid = 0; bccid < num_bccs; bccid++) { cout << sz(bvt[bccid + n]) << " "; for (auto u : bvt[bccid + n]) cout << u << " "; cout << '\n'; From 2940ca8f61efcd1e547dde0b0adcb56c9f03350d Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:48:30 -0600 Subject: [PATCH 05/16] nits --- library/graphs/bridges_cuts/bridges.hpp | 3 +-- library/graphs/bridges_cuts/cuts.hpp | 7 +++---- library/graphs/strongly_connected_components/scc.hpp | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index e9ec6c18..cefc1e4d 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -19,8 +19,7 @@ //! br_id[v] = id, 0<=id -tuple bridges(const G& adj, int m) { +template auto bridges(const G& adj, int m) { int n = sz(adj), num_ccs = 0, timer = 0; vi br_id(n, -1), is_br(m), tin(n), st; auto dfs = [&](auto&& self, int v, int p_id) -> int { diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index f1d14043..3b0ba566 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -3,7 +3,7 @@ //! @code //! { //! vector> adj(n); -//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m); +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); //! } //! vector>> adj(n); //! rep (i, 0, m) { @@ -14,14 +14,13 @@ //! adj[u].push_back({v, i}); //! adj[v].push_back({u, i}); //! } -//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m); +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); //! @endcode //! is_cut[v] = 1 iff cut node //! bcc_id[edge id] = id, 0<=id -tuple cuts(const G& adj, int m) { +template auto cuts(const G& adj, int m) { int n = sz(adj), num_bccs = 0, timer = 0; vi bcc_id(m, -1), is_cut(n), tin(n), st; auto dfs = [&](auto&& self, int v, int p_id) -> int { diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 0b2b1e8c..fe47b444 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -12,7 +12,7 @@ //! for each edge u -> v: scc_id[u] >= scc_id[v] //! @time O(n + m) //! @space O(n) -template pair sccs(const G& adj) { +template auto sccs(const G& adj) { int n = sz(adj), num_sccs = 0, timer = 0; vi scc_id(n, -1), tin(n), st; auto dfs = [&](auto&& self, int v) -> int { From 2a5a527487be9478c4f786a48f215754551d94ea Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:53:27 -0600 Subject: [PATCH 06/16] fix --- library/graphs/bridges_cuts/bridges.hpp | 2 +- library/graphs/bridges_cuts/cuts.hpp | 2 +- library/graphs/strongly_connected_components/scc.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index cefc1e4d..b063b76b 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -37,5 +37,5 @@ template auto bridges(const G& adj, int m) { return low; }; rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); - return {num_ccs, br_id, is_br}; + return tuple{num_ccs, br_id, is_br}; } diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index 3b0ba566..8d7b8ce9 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -49,5 +49,5 @@ template auto cuts(const G& adj, int m) { return low; }; rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1); - return {num_bccs, bcc_id, is_cut}; + return tuple{num_bccs, bcc_id, is_cut}; } diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index fe47b444..83308334 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -29,5 +29,5 @@ template auto sccs(const G& adj) { return low; }; rep(i, 0, n) if (!tin[i]) dfs(dfs, i); - return {num_sccs, scc_id}; + return pair{num_sccs, scc_id}; } From b8fe7027c86922dd0232882c87ee91d30e50f9cf Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 18:55:18 -0600 Subject: [PATCH 07/16] auto --- library/graphs/strongly_connected_components/scc.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/graphs/strongly_connected_components/scc.hpp b/library/graphs/strongly_connected_components/scc.hpp index 83308334..90fbc8ce 100644 --- a/library/graphs/strongly_connected_components/scc.hpp +++ b/library/graphs/strongly_connected_components/scc.hpp @@ -12,7 +12,7 @@ //! for each edge u -> v: scc_id[u] >= scc_id[v] //! @time O(n + m) //! @space O(n) -template auto sccs(const G& adj) { +auto sccs(const auto& adj) { int n = sz(adj), num_sccs = 0, timer = 0; vi scc_id(n, -1), tin(n), st; auto dfs = [&](auto&& self, int v) -> int { From a4fa7f76cb07192ddda0db67869e4fd69aeca912 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:08:24 -0600 Subject: [PATCH 08/16] switch to auto --- library/graphs/complement_graph_ccs.hpp | 3 +- library/graphs/dijkstra.hpp | 3 +- library/graphs/hopcroft_karp.hpp | 4 +-- library/strings/manacher/is_palindrome.hpp | 4 +-- .../strings/manacher/longest_from_index.hpp | 2 +- .../manacher/longest_palindrome_query.hpp | 4 +-- library/strings/manacher/manacher.hpp | 2 +- library/strings/suffix_array/suffix_array.hpp | 5 ++- .../suffix_array/suffix_array_short.hpp | 4 +-- .../ladder_decomposition/linear_kth_par.hpp | 5 +-- library/trees/lca_rmq/lca_rmq.hpp | 4 +-- library/trees/linear_kth_path.hpp | 8 ++--- library/trees/linear_lca.hpp | 5 +-- library/trees/subtree_isomorphism.hpp | 33 +++++++++---------- library/trees/tree_lift/tree_lift.hpp | 4 +-- 15 files changed, 43 insertions(+), 47 deletions(-) diff --git a/library/graphs/complement_graph_ccs.hpp b/library/graphs/complement_graph_ccs.hpp index 89864b12..79c0aba7 100644 --- a/library/graphs/complement_graph_ccs.hpp +++ b/library/graphs/complement_graph_ccs.hpp @@ -13,8 +13,7 @@ //! cc in the compliment graph //! @time O(n + m) //! @space O(n) -template -vi get_complement_graph_ccs(const G& adj) { +vi get_complement_graph_ccs(const auto& 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 7b35db28..b9995eb2 100644 --- a/library/graphs/dijkstra.hpp +++ b/library/graphs/dijkstra.hpp @@ -10,8 +10,7 @@ //! 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) { +vector dijkstra(const auto& 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 aad23130..a97501b9 100644 --- a/library/graphs/hopcroft_karp.hpp +++ b/library/graphs/hopcroft_karp.hpp @@ -18,11 +18,11 @@ //! 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 { +struct hopcroft_karp { int m_sz = 0; vi to_r, to_l; vector mvc_l, mvc_r; - hopcroft_karp(const G& adj, int rsz): + hopcroft_karp(const auto& adj, int rsz): to_r(sz(adj), -1), to_l(rsz, -1) { int lsz = sz(adj); while (1) { diff --git a/library/strings/manacher/is_palindrome.hpp b/library/strings/manacher/is_palindrome.hpp index 74a2f00f..f5a483c6 100644 --- a/library/strings/manacher/is_palindrome.hpp +++ b/library/strings/manacher/is_palindrome.hpp @@ -2,9 +2,9 @@ #include "manacher.hpp" //! @time O(n + q) //! @space O(n) -template struct pal_query { +struct pal_query { vi man; - pal_query(const T& s): man(manacher(s)) {}; + pal_query(const auto& s): man(manacher(s)) {}; bool is_pal(int l, int r) { // [l, r] return man[l + r] <= l; } diff --git a/library/strings/manacher/longest_from_index.hpp b/library/strings/manacher/longest_from_index.hpp index c2bb25b5..cceede51 100644 --- a/library/strings/manacher/longest_from_index.hpp +++ b/library/strings/manacher/longest_from_index.hpp @@ -8,7 +8,7 @@ //! is a palindrome //! @time O(n) //! @space O(n) -template vi longest_from_index(pal_query& pq) { +vi longest_from_index(pal_query& pq) { int n = (sz(pq.man) + 1) / 2; vector longest(n, n - 1); for (int i = n - 2; i >= 0; i--) { diff --git a/library/strings/manacher/longest_palindrome_query.hpp b/library/strings/manacher/longest_palindrome_query.hpp index b5491a89..dd9c753b 100644 --- a/library/strings/manacher/longest_palindrome_query.hpp +++ b/library/strings/manacher/longest_palindrome_query.hpp @@ -3,13 +3,13 @@ #include "manacher.hpp" //! queries for longest palindromic substring of a given //! substring -template struct longest_pal_query { +struct longest_pal_query { vi man; RMQ> rmq = {{}, NULL}; //! @param s string/vector //! @time O(n log n) //! @space O(n log n) for rmq, everything else is O(n) - longest_pal_query(const T& s): man(manacher(s)) { + longest_pal_query(const auto& s): man(manacher(s)) { vi init(sz(man)); iota(all(init), 0); rmq = {init, [&](int i1, int i2) { diff --git a/library/strings/manacher/manacher.hpp b/library/strings/manacher/manacher.hpp index 566b0593..d35d1405 100644 --- a/library/strings/manacher/manacher.hpp +++ b/library/strings/manacher/manacher.hpp @@ -16,7 +16,7 @@ //! //! @time O(n) //! @space O(n) -template vi manacher(const T& s) { +vi manacher(const auto& s) { int n = sz(s), p = 0; vi man(2 * n - 1); rep(i, 0, 2 * n - 1) { diff --git a/library/strings/suffix_array/suffix_array.hpp b/library/strings/suffix_array/suffix_array.hpp index 27ff90be..34b80a80 100644 --- a/library/strings/suffix_array/suffix_array.hpp +++ b/library/strings/suffix_array/suffix_array.hpp @@ -34,8 +34,7 @@ //! //! @time O(nlogn + max_num) //! @space O(n + max_num) -template -array get_sa(const T& s, int max_num) { +auto get_sa(const auto& s, int max_num) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); iota(all(sa), 0); @@ -67,5 +66,5 @@ array get_sa(const T& s, int max_num) { sz++; lcp[sa_inv[i] - 1] = sz; } - return {sa, sa_inv, lcp}; + return tuple{sa, sa_inv, lcp}; } diff --git a/library/strings/suffix_array/suffix_array_short.hpp b/library/strings/suffix_array/suffix_array_short.hpp index 65c6044c..94ed3382 100644 --- a/library/strings/suffix_array/suffix_array_short.hpp +++ b/library/strings/suffix_array/suffix_array_short.hpp @@ -10,7 +10,7 @@ //! runs in ~1.5s for 5e5 //! @time O(n * log^2(n)) //! @space O(n) -template array sa_short(const T& s) { +auto sa_short(const auto& s) { int n = sz(s); vi sa(n), sa_inv(all(s)), lcp(n - 1); iota(all(sa), 0); @@ -33,5 +33,5 @@ template array sa_short(const T& s) { sz++; lcp[sa_inv[i] - 1] = sz; } - return {sa, sa_inv, lcp}; + return tuple{sa, sa_inv, lcp}; } diff --git a/library/trees/ladder_decomposition/linear_kth_par.hpp b/library/trees/ladder_decomposition/linear_kth_par.hpp index 20d1f14d..3587a97d 100644 --- a/library/trees/ladder_decomposition/linear_kth_par.hpp +++ b/library/trees/ladder_decomposition/linear_kth_par.hpp @@ -12,14 +12,15 @@ //! kth_par = a node k edges up from v //! @time O(n + q) //! @space O(n) -template struct linear_kth_par { +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 G& adj): t(sz(adj)), j(2 * sz(t)) { + linear_kth_par(const auto& 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 b6cd12ae..c445e963 100644 --- a/library/trees/lca_rmq/lca_rmq.hpp +++ b/library/trees/lca_rmq/lca_rmq.hpp @@ -12,13 +12,13 @@ //! @time O(nlogn + q) //! @space O(nlogn) // NOLINTNEXTLINE(readability-identifier-naming) -template struct LCA { +struct LCA { struct node { int in, sub_sz = 1, d, p = -1; }; vector t; RMQ> rmq = {{}, NULL}; - LCA(const G& adj): t(sz(adj)) { + LCA(const auto& 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 8b1af4cd..29f1277b 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" -template struct linear_kth_path { - linear_lca lin_lca; - linear_kth_par lin_kp; - linear_kth_path(const G& adj): +struct linear_kth_path { + linear_lca lin_lca; + linear_kth_par lin_kp; + linear_kth_path(const auto& 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 d5789678..90aecaad 100644 --- a/library/trees/linear_lca.hpp +++ b/library/trees/linear_lca.hpp @@ -10,13 +10,14 @@ //! @endcode //! @time O(n + q) //! @space O(n) -template struct linear_lca { +struct linear_lca { struct node { int d, label, asc; }; vector t; vi head; - linear_lca(const G& adj): t(sz(adj)), head(sz(t) + 1) { + linear_lca(const auto& 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 a908ef8c..f7fd2dcf 100644 --- a/library/trees/subtree_isomorphism.hpp +++ b/library/trees/subtree_isomorphism.hpp @@ -13,21 +13,18 @@ //! isomorphic to subtree v //! @time O(n log n) //! @space O(n) -template struct subtree_iso { - int num_distinct_subtrees; - vi iso_id; - subtree_iso(const G& adj): iso_id(sz(adj), -1) { - map hashes; - auto dfs = [&](auto&& self, int v, int p) -> int { - vi ch_ids; - for (int u : adj[v]) - if (u != p) ch_ids.push_back(self(self, u, v)); - ranges::sort(ch_ids); - return iso_id[v] = - hashes.try_emplace(ch_ids, sz(hashes)) - .first->second; - }; - rep(i, 0, sz(adj)) if (iso_id[i] == -1) dfs(dfs, i, i); - num_distinct_subtrees = sz(hashes); - } -}; +auto subtree_iso(const auto& adj) { + vi iso_id(sz(adj), -1); + map hashes; + auto dfs = [&](auto&& self, int v, int p) -> int { + vi ch_ids; + for (int u : adj[v]) + if (u != p) ch_ids.push_back(self(self, u, v)); + ranges::sort(ch_ids); + return iso_id[v] = + hashes.try_emplace(ch_ids, sz(hashes)) + .first->second; + }; + rep(i, 0, sz(adj)) if (iso_id[i] == -1) dfs(dfs, i, i); + return pair{sz(hashes), iso_id}; +} diff --git a/library/trees/tree_lift/tree_lift.hpp b/library/trees/tree_lift/tree_lift.hpp index 6a0bb0a5..b2083eba 100644 --- a/library/trees/tree_lift/tree_lift.hpp +++ b/library/trees/tree_lift/tree_lift.hpp @@ -12,12 +12,12 @@ //! kth_p = a node k edges up from v //! @time O(n + q log n) //! @space O(n) -template struct tree_lift { +struct tree_lift { struct node { int d, p = -1, j = -1; }; vector t; - tree_lift(const G& adj): t(sz(adj)) { + tree_lift(const auto& 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 58ab6d0e03ca870acb1dc07b7a0499ca608dc01f Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:09:50 -0600 Subject: [PATCH 09/16] don't use pedantic to have extra golf --- tests/.config/.gcc_compile_flags | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/.config/.gcc_compile_flags b/tests/.config/.gcc_compile_flags index 31432443..5babab28 100644 --- a/tests/.config/.gcc_compile_flags +++ b/tests/.config/.gcc_compile_flags @@ -1,7 +1,6 @@ -Wall -Wextra -Wunused --Wpedantic -Wlogical-op -Wformat=2 -Wfloat-equal From c0319a3ab64630337d4f04b058794759a2aa5c36 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:14:20 -0600 Subject: [PATCH 10/16] do these now --- library/graphs/bridges_cuts/block_vertex_tree.hpp | 3 +-- library/graphs/bridges_cuts/bridge_tree.hpp | 3 +-- library/graphs/bridges_cuts/bridges.hpp | 2 +- library/graphs/bridges_cuts/cuts.hpp | 2 +- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index 8d076196..2e62ac6a 100644 --- a/library/graphs/bridges_cuts/block_vertex_tree.hpp +++ b/library/graphs/bridges_cuts/block_vertex_tree.hpp @@ -21,8 +21,7 @@ //! [n, n + num_bccs) are BCC nodes //! @time O(n + m) //! @time O(n) -template -vector block_vertex_tree(const G& adj, int num_bccs, +vector block_vertex_tree(const auto& adj, int num_bccs, const vi& bcc_id) { int n = sz(adj); vector bvt(n + num_bccs); diff --git a/library/graphs/bridges_cuts/bridge_tree.hpp b/library/graphs/bridges_cuts/bridge_tree.hpp index a668fdc5..d71d390b 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -12,8 +12,7 @@ //! @endcode //! @time O(n + m) //! @space O(n) -template -vector bridge_tree(const G& adj, int num_ccs, +vector bridge_tree(const auto& adj, int num_ccs, const vi& br_id, const vi& is_br) { vector tree(num_ccs); rep(i, 0, sz(adj)) for (auto [u, e_id] : adj[i]) if ( diff --git a/library/graphs/bridges_cuts/bridges.hpp b/library/graphs/bridges_cuts/bridges.hpp index b063b76b..e9c90866 100644 --- a/library/graphs/bridges_cuts/bridges.hpp +++ b/library/graphs/bridges_cuts/bridges.hpp @@ -19,7 +19,7 @@ //! br_id[v] = id, 0<=id auto bridges(const G& adj, int m) { +auto bridges(const auto& adj, int m) { int n = sz(adj), num_ccs = 0, timer = 0; vi br_id(n, -1), is_br(m), tin(n), st; auto dfs = [&](auto&& self, int v, int p_id) -> int { diff --git a/library/graphs/bridges_cuts/cuts.hpp b/library/graphs/bridges_cuts/cuts.hpp index 8d7b8ce9..d0ea0f4c 100644 --- a/library/graphs/bridges_cuts/cuts.hpp +++ b/library/graphs/bridges_cuts/cuts.hpp @@ -20,7 +20,7 @@ //! bcc_id[edge id] = id, 0<=id auto cuts(const G& adj, int m) { +auto cuts(const auto& adj, int m) { int n = sz(adj), num_bccs = 0, timer = 0; vi bcc_id(m, -1), is_cut(n), tin(n), st; auto dfs = [&](auto&& self, int v, int p_id) -> int { From 98039c0d40dafd27fd7f2d6f6fdf3004959f9b37 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:24:59 -0600 Subject: [PATCH 11/16] more changes --- library/contest/random.hpp | 4 ++-- library/data_structures/dsu/range_parallel_dsu.hpp | 6 ++---- .../data_structures/seg_tree_uncommon/find_first.hpp | 11 ++++------- .../data_structures/seg_tree_uncommon/find_last.hpp | 8 +++----- library/graphs/enumerate_triangles.hpp | 3 +-- library/monotonic_stack/cartesian_k_ary_tree.hpp | 3 +-- library/monotonic_stack/monotonic_stack.hpp | 3 +-- .../longest_common_subsequence/lcs_queries.hpp | 3 +-- library/strings/prefix_function.hpp | 2 +- library/strings/wildcard_pattern_matching.hpp | 3 +-- 10 files changed, 17 insertions(+), 29 deletions(-) diff --git a/library/contest/random.hpp b/library/contest/random.hpp index 8e77c630..c6b3302e 100644 --- a/library/contest/random.hpp +++ b/library/contest/random.hpp @@ -9,7 +9,7 @@ //! @endcode mt19937 rng( chrono::steady_clock::now().time_since_epoch().count()); -template T rnd(T l, T r) { +auto rnd(auto l, auto r) { assert(l <= r); - return uniform_int_distribution(l, r)(rng); + return uniform_int_distribution(l, r)(rng); } diff --git a/library/data_structures/dsu/range_parallel_dsu.hpp b/library/data_structures/dsu/range_parallel_dsu.hpp index f22d5017..e945a35b 100644 --- a/library/data_structures/dsu/range_parallel_dsu.hpp +++ b/library/data_structures/dsu/range_parallel_dsu.hpp @@ -8,16 +8,14 @@ struct rp_dsu { vector ufs; rp_dsu(int n): ufs(bit_width(unsigned(n)), UF(n)) {} - template - void join(int l1, int l2, int len, const F& f) { + void join(int l1, int l2, int len, const auto& f) { if (len == 0) return; int lg = __lg(len); join_impl(lg, l1, l2, f); join_impl(lg, l1 + len - (1 << lg), l2 + len - (1 << lg), f); } - template - void join_impl(int lvl, int u, int v, const F& f) { + void join_impl(int lvl, int u, int v, const auto& f) { if (lvl == 0) { u = ufs[0].find(u); v = ufs[0].find(v); diff --git a/library/data_structures/seg_tree_uncommon/find_first.hpp b/library/data_structures/seg_tree_uncommon/find_first.hpp index 84b8abc7..dcc78aa2 100644 --- a/library/data_structures/seg_tree_uncommon/find_first.hpp +++ b/library/data_structures/seg_tree_uncommon/find_first.hpp @@ -25,13 +25,11 @@ //! such element exists then `r` is returned //! @time O(log(n)) //! @space O(log(n)) for recursion stack -template -int find_first(int l, int r, const F& f) { +int find_first(int l, int r, const auto& f) { return find_first_in_range(l, r, f, 0, n, 1); } //! invariant: f(tree[v], tl, tr) is 1 -template -int find_first_in_subtree(const F& f, int tl, int tr, +int find_first_in_subtree(const auto& f, int tl, int tr, int v) { if (v >= n) return tl; int tm = split(tl, tr); @@ -40,9 +38,8 @@ int find_first_in_subtree(const F& f, int tl, int tr, return find_first_in_subtree(f, tl, tm, 2 * v); return find_first_in_subtree(f, tm, tr, 2 * v + 1); } -template -int find_first_in_range(int l, int r, const F& f, int tl, - int tr, int v) { +int find_first_in_range(int l, int r, const auto& f, + int tl, int tr, int v) { if (r <= tl || tr <= l) return r; if (l <= tl && tr <= r) return f(tree[v], tl, tr) diff --git a/library/data_structures/seg_tree_uncommon/find_last.hpp b/library/data_structures/seg_tree_uncommon/find_last.hpp index 08a015f5..74ee92c3 100644 --- a/library/data_structures/seg_tree_uncommon/find_last.hpp +++ b/library/data_structures/seg_tree_uncommon/find_last.hpp @@ -25,12 +25,11 @@ //! such element exists then (l - 1) is returned //! @time O(log(n)) //! @space O(log(n)) for recursion stack -template int find_last(int l, int r, const F& f) { +int find_last(int l, int r, const auto& f) { return find_last_in_range(l, r, f, 0, n, 1); } //! invariant: f(tree[v], tl, tr) is 1 -template -int find_last_in_subtree(const F& f, int tl, int tr, +int find_last_in_subtree(const auto& f, int tl, int tr, int v) { if (v >= n) return tl; int tm = split(tl, tr); @@ -39,8 +38,7 @@ int find_last_in_subtree(const F& f, int tl, int tr, return find_last_in_subtree(f, tm, tr, 2 * v + 1); return find_last_in_subtree(f, tl, tm, 2 * v); } -template -int find_last_in_range(int l, int r, const F& f, int tl, +int find_last_in_range(int l, int r, const auto& f, int tl, int tr, int v) { if (r <= tl || tr <= l) return l - 1; if (l <= tl && tr <= r) diff --git a/library/graphs/enumerate_triangles.hpp b/library/graphs/enumerate_triangles.hpp index 7d9af9b0..5c50437d 100644 --- a/library/graphs/enumerate_triangles.hpp +++ b/library/graphs/enumerate_triangles.hpp @@ -7,9 +7,8 @@ //! @endcode //! @time O(n + m ^ (3/2)) //! @space O(n + m) -template void enumerate_triangles(const vector& edges, int n, - F f) { + auto f) { vi deg(n); for (auto [u, v] : edges) deg[u]++, deg[v]++; vector adj(n); diff --git a/library/monotonic_stack/cartesian_k_ary_tree.hpp b/library/monotonic_stack/cartesian_k_ary_tree.hpp index 45390b7d..dc3d3184 100644 --- a/library/monotonic_stack/cartesian_k_ary_tree.hpp +++ b/library/monotonic_stack/cartesian_k_ary_tree.hpp @@ -31,8 +31,7 @@ //! @returns parent array //! @time O(n) //! @space a O(n) vector is allocated and returned -template -vi cart_k_ary_tree(const vector& a, const vi& l) { +vi cart_k_ary_tree(const auto& a, const vi& l) { vi p(l); for (int i = sz(a) - 1; i >= 0; i--) for (int j = i - 1; j != l[i]; j = l[j]) diff --git a/library/monotonic_stack/monotonic_stack.hpp b/library/monotonic_stack/monotonic_stack.hpp index cb78968a..42615a62 100644 --- a/library/monotonic_stack/monotonic_stack.hpp +++ b/library/monotonic_stack/monotonic_stack.hpp @@ -7,8 +7,7 @@ //! a[le[i]] < a[i] //! @time O(n) //! @space O(n) -template -vi mono_st(const vector& a, F cmp) { +vi mono_st(const auto& a, auto cmp) { vi l(sz(a)); rep(i, 0, sz(a)) for ( l[i] = i - 1; l[i] >= 0 && !cmp(a[l[i]], a[i]);) l[i] = diff --git a/library/strings/longest_common_subsequence/lcs_queries.hpp b/library/strings/longest_common_subsequence/lcs_queries.hpp index 4abe4bf3..25c2872d 100644 --- a/library/strings/longest_common_subsequence/lcs_queries.hpp +++ b/library/strings/longest_common_subsequence/lcs_queries.hpp @@ -13,8 +13,7 @@ //! )) //! @time O(n*m*log(m) + q*log(m) + q*log(q)) //! @space O(n + m + q) -template -vi lcs_queries(const T& s, const T& t, +vi lcs_queries(const auto& s, const auto& t, const vector>& queries) { int n = sz(s), m = sz(t), q = sz(queries); vector>> qs(n); diff --git a/library/strings/prefix_function.hpp b/library/strings/prefix_function.hpp index b5d5ea91..103db3b1 100644 --- a/library/strings/prefix_function.hpp +++ b/library/strings/prefix_function.hpp @@ -2,7 +2,7 @@ //! https://cp-algorithms.com/string/prefix-function.html#implementation //! @time O(n) //! @space O(n) -template vi prefix_function(const T& s) { +vi prefix_function(const auto& s) { vi pi(sz(s)); rep(i, 1, sz(s)) { int j = pi[i - 1]; diff --git a/library/strings/wildcard_pattern_matching.hpp b/library/strings/wildcard_pattern_matching.hpp index 01a06727..acb05138 100644 --- a/library/strings/wildcard_pattern_matching.hpp +++ b/library/strings/wildcard_pattern_matching.hpp @@ -19,9 +19,8 @@ vector make_powers(const vl& v) { } return pws; } -template vector wildcard_pattern_matching(const vl& s, - const vl& t, F conv) { + const vl& t, auto conv) { int n = sz(s), m = sz(t); auto s_pws = make_powers(s); auto t_pws = make_powers(t); From 63996c404c7209562e221cc1b523c9abca4e58e2 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:35:28 -0600 Subject: [PATCH 12/16] update --- .../data_structures/deque_op.test.cpp | 2 +- .../graphs/directed_cycle.test.cpp | 6 +++--- .../handmade_tests/fib_matrix_expo.test.cpp | 2 +- .../handmade_tests/mod_int.test.cpp | 2 +- tests/library_checker_aizu_tests/mono_st_asserts.hpp | 5 ++--- .../strings/lcp_query_zfunc.test.cpp | 12 ++++++------ .../strings/single_matching_bs.test.cpp | 2 +- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/tests/library_checker_aizu_tests/data_structures/deque_op.test.cpp b/tests/library_checker_aizu_tests/data_structures/deque_op.test.cpp index 857c7092..a43f9e19 100644 --- a/tests/library_checker_aizu_tests/data_structures/deque_op.test.cpp +++ b/tests/library_checker_aizu_tests/data_structures/deque_op.test.cpp @@ -52,7 +52,7 @@ int main() { assert(stl_dq.front() == dq.front()); assert(stl_dq.back() == dq.back()); for (int index_tests = 10; index_tests--;) { - int idx = rnd(0, dq.siz() - 1); + int idx = rnd(0, dq.siz() - 1); assert(stl_dq[idx] == dq[idx]); } } diff --git a/tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp b/tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp index 827300cf..54089b4b 100644 --- a/tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp +++ b/tests/library_checker_aizu_tests/graphs/directed_cycle.test.cpp @@ -16,7 +16,7 @@ int main() { adj_edge_id[u].emplace_back(v, i); } scc_asserts(adj); - sccs scc(adj); + auto [num_sccs, scc_id] = sccs(adj); vector color(n); vector< pair> @@ -35,7 +35,7 @@ int main() { auto [curr_edge_id, curr_node] = edge_stack.back(); edge_stack.pop_back(); - assert(scc.scc_id[curr_node] == scc.scc_id[u]); + assert(scc_id[curr_node] == scc_id[u]); res.push_back(curr_edge_id); if (curr_node == v) break; } @@ -53,7 +53,7 @@ int main() { color[i] = 2; } } - assert(scc.num_sccs == n); + assert(num_sccs == n); cout << -1 << '\n'; return 0; } diff --git a/tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp index 084ec947..5aa467aa 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/fib_matrix_expo.test.cpp @@ -31,7 +31,7 @@ int main() { assert(fib(5)[0] == 5); for (int i = 0; i < 500; i++) check(i); for (int tests = 1000; tests--;) - check(rnd(0, LLONG_MAX)); + check(rnd(0LL, LLONG_MAX)); cout << "Hello World\n"; return 0; } diff --git a/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp index 4eaf9546..4520bab2 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/mod_int.test.cpp @@ -16,7 +16,7 @@ int main() { for (int i = 0; i < 1'000'000; i++) { int type = rnd(0, 5); if (type == 0) { - mod = mods[rnd(0, sz(mods) - 1)]; + mod = mods[rnd(0, int(sz(mods)) - 1)]; val = rnd(-mod + 1, mod - 1); assert(0 <= val.x && val.x < mod); } else if (type == 1) { diff --git a/tests/library_checker_aizu_tests/mono_st_asserts.hpp b/tests/library_checker_aizu_tests/mono_st_asserts.hpp index 706f340b..fe8c18b7 100644 --- a/tests/library_checker_aizu_tests/mono_st_asserts.hpp +++ b/tests/library_checker_aizu_tests/mono_st_asserts.hpp @@ -69,9 +69,8 @@ void mono_st_asserts(const vector& a) { assert(iterations == n); } { - vector old_way_ri = - mono_st({rbegin(a), rend(a)}, - [&](int x, int y) { return !cmp(y, x); }); + vector old_way_ri = mono_st(vi{rbegin(a), rend(a)}, + [&](int x, int y) { return !cmp(y, x); }); reverse(begin(old_way_ri), end(old_way_ri)); transform(begin(old_way_ri), end(old_way_ri), begin(old_way_ri), diff --git a/tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp b/tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp index 1cffd6de..2907240b 100644 --- a/tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp +++ b/tests/library_checker_aizu_tests/strings/lcp_query_zfunc.test.cpp @@ -12,16 +12,16 @@ int main() { // test `*_cmp` functions { for (int num_tests = 50; num_tests--;) { - auto l = rnd(0, sz(s) - 1); - auto r = rnd(0, sz(s) - 1); + auto l = rnd(0, int(sz(s)) - 1); + auto r = rnd(0, int(sz(s)) - 1); int cmp_val = lq.cmp_sufs(l, r); if (cmp_val < 0) assert(s.substr(l) < s.substr(r)); if (cmp_val == 0) assert(s.substr(l) == s.substr(r)); if (cmp_val > 0) assert(s.substr(l) > s.substr(r)); } for (int num_tests = 50; num_tests--;) { - auto l1 = rnd(0, sz(s)); - auto r1 = rnd(0, sz(s)); + auto l1 = rnd(0, int(sz(s))); + auto r1 = rnd(0, int(sz(s))); if (l1 > r1) swap(l1, r1); if (l1 == sz(s)) l1--; int l2, r2; @@ -29,8 +29,8 @@ int main() { l2 = l1; r2 = r1; } else { - l2 = rnd(0, sz(s)); - r2 = rnd(0, sz(s)); + l2 = rnd(0, int(sz(s))); + r2 = rnd(0, int(sz(s))); if (l2 > r2) swap(l2, r2); if (l2 == sz(s)) l2--; } diff --git a/tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp b/tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp index 2414dcbc..a538460a 100644 --- a/tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp +++ b/tests/library_checker_aizu_tests/strings/single_matching_bs.test.cpp @@ -49,7 +49,7 @@ int main() { for (int num_tests = 10; num_tests--;) { vector splits = {0, int(sz(t))}; for (int num_splits = rnd(0, 4); num_splits--;) - splits.push_back(rnd(0, sz(t) - 1)); + splits.push_back(rnd(0, int(sz(t)) - 1)); sort(begin(splits), end(splits)); vector> subs; for (int i = 1; i < sz(splits); i++) From b14fb78d3bad90a0053118d6f9a70c3074bcef9b Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:38:22 -0600 Subject: [PATCH 13/16] fix --- tests/library_checker_aizu_tests/compress_tree_asserts.hpp | 2 +- .../handmade_tests/n_choose_k.test.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/library_checker_aizu_tests/compress_tree_asserts.hpp b/tests/library_checker_aizu_tests/compress_tree_asserts.hpp index 2f32da3d..935ade3e 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/n_choose_k.test.cpp b/tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp index 7a15a854..9e2f8319 100644 --- a/tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp +++ b/tests/library_checker_aizu_tests/handmade_tests/n_choose_k.test.cpp @@ -26,8 +26,8 @@ int main() { } } for (int tests = 100'000; tests--;) { - auto n = rnd(-1e18, 1e18); - auto k = rnd(-mod, mod - 1); + auto n = rnd(int64_t(-1e18), int64_t(1e18)); + auto k = rnd(-mod, mod - 1); assert(lucas(n, k) == c_small_k(n, k)); } assert(lucas(371283LL, 32981LL) == 0); From e6006c87b3ee91742812aab3826133a884c84f57 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:41:41 -0600 Subject: [PATCH 14/16] update --- tests/.config/.clang_compile_flags | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/.config/.clang_compile_flags b/tests/.config/.clang_compile_flags index 52398457..ad873187 100644 --- a/tests/.config/.clang_compile_flags +++ b/tests/.config/.clang_compile_flags @@ -12,3 +12,4 @@ -O2 -Wno-narrowing -Wno-deprecated-declarations +-Wno-gnu-conditional-omitted-operand From 2e82d707a4335a1d7c40208ce196a6983feaa05d Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:46:48 -0600 Subject: [PATCH 15/16] fixes --- library/contest/random.hpp | 2 +- library/graphs/bridges_cuts/block_vertex_tree.hpp | 10 ++++++---- library/graphs/bridges_cuts/bridge_tree.hpp | 10 ++++++---- library/trees/subtree_isomorphism.hpp | 3 ++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/library/contest/random.hpp b/library/contest/random.hpp index c6b3302e..9a868d3e 100644 --- a/library/contest/random.hpp +++ b/library/contest/random.hpp @@ -5,7 +5,7 @@ //! uint64_t x1 = rng(); //! mt19937 rng; // fixed seed for debugging //! int x2 = rnd(0, 1); //random number in [0,1] -//! ll x3 = rnd(1, 1e18); +//! ll x3 = rnd(ll(1), ll(1e18)); //! @endcode mt19937 rng( chrono::steady_clock::now().time_since_epoch().count()); diff --git a/library/graphs/bridges_cuts/block_vertex_tree.hpp b/library/graphs/bridges_cuts/block_vertex_tree.hpp index 2e62ac6a..23702ac2 100644 --- a/library/graphs/bridges_cuts/block_vertex_tree.hpp +++ b/library/graphs/bridges_cuts/block_vertex_tree.hpp @@ -3,12 +3,14 @@ //! @code //! { //! vector> adj(n); -//! cuts cc(adj, m); -//! vector bvt = block_vertex_tree(adj, cc); +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); +//! vector bvt = block_vertex_tree(adj, +//! num_bccs, bcc_id); //! } //! vector>> adj(n); -//! cuts cc(adj, m); -//! vector bvt = block_vertex_tree(adj, cc); +//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m); +//! vector bvt = block_vertex_tree(adj, +//! num_bccs, bcc_id); //! //! //to loop over each unique bcc containing a node u: //! for (int bccid : bvt[v]) { diff --git a/library/graphs/bridges_cuts/bridge_tree.hpp b/library/graphs/bridges_cuts/bridge_tree.hpp index d71d390b..a328c772 100644 --- a/library/graphs/bridges_cuts/bridge_tree.hpp +++ b/library/graphs/bridges_cuts/bridge_tree.hpp @@ -3,12 +3,14 @@ //! @code //! { //! vector> adj(n); -//! bridges br(adj, m); -//! vector bt = bridge_tree(adj, br); +//! auto [num_ccs, br_id, is_br] = bridges(adj, m); +//! vector bt = bridge_tree(adj, +//! num_ccs, br_id, is_br); //! } //! vector>> adj(n); -//! bridges br(adj, m); -//! vector bt = bridge_tree(adj, br); +//! auto [num_ccs, br_id, is_br] = bridges(adj, m); +//! vector bt = bridge_tree(adj, +//! num_ccs, br_id, is_br); //! @endcode //! @time O(n + m) //! @space O(n) diff --git a/library/trees/subtree_isomorphism.hpp b/library/trees/subtree_isomorphism.hpp index f7fd2dcf..c50f1e0d 100644 --- a/library/trees/subtree_isomorphism.hpp +++ b/library/trees/subtree_isomorphism.hpp @@ -6,7 +6,8 @@ //! subtree_iso(adj); //! } //! vector> adj(n); -//! subtree_iso iso(adj); +//! auto [num_distinct_subtrees, iso_id] = +//! subtree_iso(adj); //! @endcode //! - 0 <= iso_id[v] < num_distinct_subtrees //! - iso_id[u] == iso_id[v] iff subtree u is From 4157fbf0d7b4dbec6dd31370ac042a589a6f8475 Mon Sep 17 00:00:00 2001 From: Luke Videckis Date: Sat, 14 Dec 2024 19:48:35 -0600 Subject: [PATCH 16/16] fix --- tests/.config/.cppcheck_suppression_list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/.config/.cppcheck_suppression_list b/tests/.config/.cppcheck_suppression_list index 285a9ef6..e069fe4a 100644 --- a/tests/.config/.cppcheck_suppression_list +++ b/tests/.config/.cppcheck_suppression_list @@ -51,7 +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:63 +knownConditionTrueFalse:../library/strings/suffix_array/suffix_array.hpp:62 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 +functionStatic:../library/monotonic_stack/monotonic_stack.hpp:10