Skip to content

Commit a3f5767

Browse files
authored
Golf scc and auto param (#121)
* golf * update bridges * golf bridges now * convert this now * nits * fix * auto * switch to auto * don't use pedantic to have extra golf * do these now * more changes * update * fix * update * fixes * fix
1 parent ad2ca6d commit a3f5767

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+212
-243
lines changed

library/contest/random.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
//! uint64_t x1 = rng();
66
//! mt19937 rng; // fixed seed for debugging
77
//! int x2 = rnd(0, 1); //random number in [0,1]
8-
//! ll x3 = rnd<ll>(1, 1e18);
8+
//! ll x3 = rnd(ll(1), ll(1e18));
99
//! @endcode
1010
mt19937 rng(
1111
chrono::steady_clock::now().time_since_epoch().count());
12-
template<class T> T rnd(T l, T r) {
12+
auto rnd(auto l, auto r) {
1313
assert(l <= r);
14-
return uniform_int_distribution<T>(l, r)(rng);
14+
return uniform_int_distribution(l, r)(rng);
1515
}

library/data_structures/dsu/range_parallel_dsu.hpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@
88
struct rp_dsu {
99
vector<UF> ufs;
1010
rp_dsu(int n): ufs(bit_width(unsigned(n)), UF(n)) {}
11-
template<class F>
12-
void join(int l1, int l2, int len, const F& f) {
11+
void join(int l1, int l2, int len, const auto& f) {
1312
if (len == 0) return;
1413
int lg = __lg(len);
1514
join_impl(lg, l1, l2, f);
1615
join_impl(lg, l1 + len - (1 << lg),
1716
l2 + len - (1 << lg), f);
1817
}
19-
template<class F>
20-
void join_impl(int lvl, int u, int v, const F& f) {
18+
void join_impl(int lvl, int u, int v, const auto& f) {
2119
if (lvl == 0) {
2220
u = ufs[0].find(u);
2321
v = ufs[0].find(v);

library/data_structures/seg_tree_uncommon/find_first.hpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,11 @@
2525
//! such element exists then `r` is returned
2626
//! @time O(log(n))
2727
//! @space O(log(n)) for recursion stack
28-
template<class F>
29-
int find_first(int l, int r, const F& f) {
28+
int find_first(int l, int r, const auto& f) {
3029
return find_first_in_range(l, r, f, 0, n, 1);
3130
}
3231
//! invariant: f(tree[v], tl, tr) is 1
33-
template<class F>
34-
int find_first_in_subtree(const F& f, int tl, int tr,
32+
int find_first_in_subtree(const auto& f, int tl, int tr,
3533
int v) {
3634
if (v >= n) return tl;
3735
int tm = split(tl, tr);
@@ -40,9 +38,8 @@ int find_first_in_subtree(const F& f, int tl, int tr,
4038
return find_first_in_subtree(f, tl, tm, 2 * v);
4139
return find_first_in_subtree(f, tm, tr, 2 * v + 1);
4240
}
43-
template<class F>
44-
int find_first_in_range(int l, int r, const F& f, int tl,
45-
int tr, int v) {
41+
int find_first_in_range(int l, int r, const auto& f,
42+
int tl, int tr, int v) {
4643
if (r <= tl || tr <= l) return r;
4744
if (l <= tl && tr <= r)
4845
return f(tree[v], tl, tr)

library/data_structures/seg_tree_uncommon/find_last.hpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@
2525
//! such element exists then (l - 1) is returned
2626
//! @time O(log(n))
2727
//! @space O(log(n)) for recursion stack
28-
template<class F> int find_last(int l, int r, const F& f) {
28+
int find_last(int l, int r, const auto& f) {
2929
return find_last_in_range(l, r, f, 0, n, 1);
3030
}
3131
//! invariant: f(tree[v], tl, tr) is 1
32-
template<class F>
33-
int find_last_in_subtree(const F& f, int tl, int tr,
32+
int find_last_in_subtree(const auto& f, int tl, int tr,
3433
int v) {
3534
if (v >= n) return tl;
3635
int tm = split(tl, tr);
@@ -39,8 +38,7 @@ int find_last_in_subtree(const F& f, int tl, int tr,
3938
return find_last_in_subtree(f, tm, tr, 2 * v + 1);
4039
return find_last_in_subtree(f, tl, tm, 2 * v);
4140
}
42-
template<class F>
43-
int find_last_in_range(int l, int r, const F& f, int tl,
41+
int find_last_in_range(int l, int r, const auto& f, int tl,
4442
int tr, int v) {
4543
if (r <= tl || tr <= l) return l - 1;
4644
if (l <= tl && tr <= r)

library/graphs/bridges_cuts/block_vertex_tree.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
//! @code
44
//! {
55
//! vector<vector<pii>> adj(n);
6-
//! cuts cc(adj, m);
7-
//! vector<vi> bvt = block_vertex_tree(adj, cc);
6+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
7+
//! vector<vi> bvt = block_vertex_tree(adj,
8+
//! num_bccs, bcc_id);
89
//! }
910
//! vector<basic_string<array<int, 2>>> adj(n);
10-
//! cuts cc(adj, m);
11-
//! vector<vi> bvt = block_vertex_tree(adj, cc);
11+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
12+
//! vector<vi> bvt = block_vertex_tree(adj,
13+
//! num_bccs, bcc_id);
1214
//!
1315
//! //to loop over each unique bcc containing a node u:
1416
//! for (int bccid : bvt[v]) {
@@ -21,15 +23,14 @@
2123
//! [n, n + num_bccs) are BCC nodes
2224
//! @time O(n + m)
2325
//! @time O(n)
24-
template<class G>
25-
vector<vi> block_vertex_tree(const G& adj,
26-
const cuts<G>& cc) {
26+
vector<vi> block_vertex_tree(const auto& adj, int num_bccs,
27+
const vi& bcc_id) {
2728
int n = sz(adj);
28-
vector<vi> bvt(n + cc.num_bccs);
29-
vector<bool> vis(cc.num_bccs);
29+
vector<vi> bvt(n + num_bccs);
30+
vector<bool> vis(num_bccs);
3031
rep(i, 0, n) {
3132
for (auto [_, e_id] : adj[i]) {
32-
int bccid = cc.bcc_id[e_id];
33+
int bccid = bcc_id[e_id];
3334
if (!vis[bccid]) {
3435
vis[bccid] = 1;
3536
bvt[i].push_back(bccid + n);

library/graphs/bridges_cuts/bridge_tree.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
//! @code
44
//! {
55
//! vector<vector<pii>> adj(n);
6-
//! bridges br(adj, m);
7-
//! vector<vi> bt = bridge_tree(adj, br);
6+
//! auto [num_ccs, br_id, is_br] = bridges(adj, m);
7+
//! vector<vi> bt = bridge_tree(adj,
8+
//! num_ccs, br_id, is_br);
89
//! }
910
//! vector<basic_string<array<int, 2>>> adj(n);
10-
//! bridges br(adj, m);
11-
//! vector<vi> bt = bridge_tree(adj, br);
11+
//! auto [num_ccs, br_id, is_br] = bridges(adj, m);
12+
//! vector<vi> bt = bridge_tree(adj,
13+
//! num_ccs, br_id, is_br);
1214
//! @endcode
1315
//! @time O(n + m)
1416
//! @space O(n)
15-
template<class G>
16-
vector<vi> bridge_tree(const G& adj,
17-
const bridges<G>& br) {
18-
vector<vi> tree(br.num_ccs);
17+
vector<vi> bridge_tree(const auto& adj, int num_ccs,
18+
const vi& br_id, const vi& is_br) {
19+
vector<vi> tree(num_ccs);
1920
rep(i, 0, sz(adj)) for (auto [u, e_id] : adj[i]) if (
20-
br.is_bridge[e_id]) tree[br.br_id[i]]
21-
.push_back(br.br_id[u]);
21+
is_br[e_id]) tree[br_id[i]]
22+
.push_back(br_id[u]);
2223
return tree;
2324
}

library/graphs/bridges_cuts/bridges.hpp

Lines changed: 23 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! @code
44
//! {
55
//! vector<vector<pii>> adj(n);
6-
//! auto [num_ccs, is_bridge, br_id] = bridges(adj, m);
6+
//! auto [num_ccs, br_id, is_br] = bridges(adj, m);
77
//! }
88
//! vector<basic_string<array<int, 2>>> adj(n);
99
//! rep (i, 0, m) {
@@ -13,36 +13,29 @@
1313
//! adj[u].push_back({v, i});
1414
//! adj[v].push_back({u, i});
1515
//! }
16-
//! auto [num_ccs, is_bridge, br_id] = bridges(adj, m);
16+
//! auto [num_ccs, br_id, is_br] = bridges(adj, m);
1717
//! @endcode
18-
//! is_bridge[edge id] = 1 iff bridge edge
18+
//! is_br[edge id] = 1 iff bridge edge
1919
//! br_id[v] = id, 0<=id<num_ccs
2020
//! @time O(n + m)
2121
//! @space O(n + m)
22-
template<class G> struct bridges {
23-
int num_ccs = 0;
24-
vector<bool> is_bridge;
25-
vi br_id;
26-
bridges(const G& adj, int m):
27-
is_bridge(m), br_id(sz(adj), -1) {
28-
int n = sz(adj), timer = 1;
29-
vi tin(n), st;
30-
auto dfs = [&](auto&& self, int v, int p_id) -> int {
31-
int low = tin[v] = timer++, siz = sz(st);
32-
st.push_back(v);
33-
for (auto [u, e_id] : adj[v]) {
34-
if (e_id == p_id) continue;
35-
if (!tin[u]) low = min(low, self(self, u, e_id));
36-
low = min(low, tin[u]);
37-
}
38-
if (tin[v] == low) {
39-
if (p_id != -1) is_bridge[p_id] = 1;
40-
rep(i, siz, sz(st)) br_id[st[i]] = num_ccs;
41-
st.resize(siz);
42-
num_ccs++;
43-
}
44-
return low;
45-
};
46-
rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1);
47-
}
48-
};
22+
auto bridges(const auto& adj, int m) {
23+
int n = sz(adj), num_ccs = 0, timer = 0;
24+
vi br_id(n, -1), is_br(m), tin(n), st;
25+
auto dfs = [&](auto&& self, int v, int p_id) -> int {
26+
int low = tin[v] = ++timer, siz = sz(st);
27+
st.push_back(v);
28+
for (auto [u, e_id] : adj[v])
29+
if (e_id != p_id && br_id[u] < 0)
30+
low = min(low, tin[u] ?: self(self, u, e_id));
31+
if (tin[v] == low) {
32+
if (p_id != -1) is_br[p_id] = 1;
33+
rep(i, siz, sz(st)) br_id[st[i]] = num_ccs;
34+
st.resize(siz);
35+
num_ccs++;
36+
}
37+
return low;
38+
};
39+
rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1);
40+
return tuple{num_ccs, br_id, is_br};
41+
}

library/graphs/bridges_cuts/cuts.hpp

Lines changed: 31 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! @code
44
//! {
55
//! vector<vector<pii>> adj(n);
6-
//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m);
6+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
77
//! }
88
//! vector<basic_string<array<int, 2>>> adj(n);
99
//! rep (i, 0, m) {
@@ -14,45 +14,40 @@
1414
//! adj[u].push_back({v, i});
1515
//! adj[v].push_back({u, i});
1616
//! }
17-
//! auto [num_bccs, is_cut, bcc_id] = cuts(adj, m);
17+
//! auto [num_bccs, bcc_id, is_cut] = cuts(adj, m);
1818
//! @endcode
1919
//! is_cut[v] = 1 iff cut node
2020
//! bcc_id[edge id] = id, 0<=id<num_bccs
2121
//! @time O(n + m)
2222
//! @space O(n + m)
23-
template<class G> struct cuts {
24-
int num_bccs = 0;
25-
vector<bool> is_cut;
26-
vi bcc_id;
27-
cuts(const G& adj, int m):
28-
is_cut(sz(adj)), bcc_id(m, -1) {
29-
int n = sz(adj), timer = 1;
30-
vi tin(n), st;
31-
auto dfs = [&](auto&& self, int v, int p_id) -> int {
32-
int low = tin[v] = timer++, deg = 0;
33-
for (auto [u, e_id] : adj[v]) {
34-
assert(v != u);
35-
if (e_id == p_id) continue;
36-
if (!tin[u]) {
37-
int siz = sz(st);
38-
st.push_back(e_id);
39-
int low_ch = self(self, u, e_id);
40-
if (low_ch >= tin[v]) {
41-
is_cut[v] = 1;
42-
rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs;
43-
st.resize(siz);
44-
num_bccs++;
45-
}
46-
low = min(low, low_ch);
47-
deg++;
48-
} else if (tin[u] < tin[v]) {
49-
st.push_back(e_id);
50-
low = min(low, tin[u]);
23+
auto cuts(const auto& adj, int m) {
24+
int n = sz(adj), num_bccs = 0, timer = 0;
25+
vi bcc_id(m, -1), is_cut(n), tin(n), st;
26+
auto dfs = [&](auto&& self, int v, int p_id) -> int {
27+
int low = tin[v] = ++timer, deg = 0;
28+
for (auto [u, e_id] : adj[v]) {
29+
assert(v != u);
30+
if (e_id == p_id) continue;
31+
if (!tin[u]) {
32+
int siz = sz(st);
33+
st.push_back(e_id);
34+
int low_ch = self(self, u, e_id);
35+
if (low_ch >= tin[v]) {
36+
is_cut[v] = 1;
37+
rep(i, siz, sz(st)) bcc_id[st[i]] = num_bccs;
38+
st.resize(siz);
39+
num_bccs++;
5140
}
41+
low = min(low, low_ch);
42+
deg++;
43+
} else if (tin[u] < tin[v]) {
44+
st.push_back(e_id);
45+
low = min(low, tin[u]);
5246
}
53-
if (p_id == -1) is_cut[v] = (deg > 1);
54-
return low;
55-
};
56-
rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1);
57-
}
58-
};
47+
}
48+
if (p_id == -1) is_cut[v] = (deg > 1);
49+
return low;
50+
};
51+
rep(i, 0, n) if (!tin[i]) dfs(dfs, i, -1);
52+
return tuple{num_bccs, bcc_id, is_cut};
53+
}

library/graphs/complement_graph_ccs.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
//! cc in the compliment graph
1414
//! @time O(n + m)
1515
//! @space O(n)
16-
template<class G>
17-
vi get_complement_graph_ccs(const G& adj) {
16+
vi get_complement_graph_ccs(const auto& adj) {
1817
int n = sz(adj);
1918
vi cc_id(n), unseen(n);
2019
iota(all(unseen), 0);

library/graphs/dijkstra.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010
//! d[v] = min dist from source->..->v
1111
//! @time O(n + (m log m))
1212
//! @space O(n + m)
13-
template<class G>
14-
vector<ll> dijkstra(const G& adj, int s) {
13+
vector<ll> dijkstra(const auto& adj, int s) {
1514
using p = pair<ll, int>;
1615
priority_queue<p, vector<p>, greater<>> pq;
1716
pq.emplace(0, s);

0 commit comments

Comments
 (0)