Skip to content

Commit a19ca8d

Browse files
authored
No more struct node (#151)
* no longer have node structs * fix compile error * fix another compile error * fixed * assume tree, not forest * fix another test * fix shadow warning * rename test now that it's not a forest * add extra member to linear lca
1 parent 4a887fd commit a19ca8d

File tree

18 files changed

+110
-188
lines changed

18 files changed

+110
-188
lines changed

library/data_structures/dsu/dsu_bipartite.hpp

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,33 @@
44
//! bipartite check
55
struct dsu_bipartite {
66
int num_sets;
7-
struct node {
8-
int p = -1;
9-
bool is_bi = 1, parity;
10-
};
11-
vector<node> t;
12-
dsu_bipartite(int n): num_sets(n), t(n) {}
7+
vi p, is_bi, parity;
8+
dsu_bipartite(int n):
9+
num_sets(n), p(n, -1), is_bi(n, 1), parity(n) {}
1310
int find(int v) {
14-
if (t[v].p < 0) return v;
15-
int root = find(t[v].p);
16-
t[v].parity ^= t[t[v].p].parity;
17-
return t[v].p = root;
11+
if (p[v] < 0) return v;
12+
int root = find(p[v]);
13+
parity[v] ^= parity[p[v]];
14+
return p[v] = root;
1815
}
1916
bool join(int u, int v) {
2017
int root_u = find(u), root_v = find(v);
2118
if (root_u == root_v) {
22-
if (t[u].parity == t[v].parity) t[root_u].is_bi = 0;
19+
if (parity[u] == parity[v]) is_bi[root_u] = 0;
2320
return 0;
2421
}
25-
if (t[root_u].p > t[root_v].p) {
22+
if (p[root_u] > p[root_v]) {
2623
swap(u, v);
2724
swap(root_u, root_v);
2825
}
29-
t[root_u].is_bi &= t[root_v].is_bi;
30-
t[root_v].parity = t[v].parity ^ 1 ^ t[u].parity;
31-
t[root_u].p += t[root_v].p, t[root_v].p = root_u,
32-
num_sets--;
26+
is_bi[root_u] &= is_bi[root_v];
27+
parity[root_v] = parity[v] ^ 1 ^ parity[u];
28+
p[root_u] += p[root_v], p[root_v] = root_u, num_sets--;
3329
return 1;
3430
}
35-
int size(int v) { return -t[find(v)].p; }
31+
int size(int v) { return -p[find(v)]; }
3632
bool same_set(int u, int v) {
3733
return find(u) == find(v);
3834
}
39-
bool is_bipartite(int v) { return t[find(v)].is_bi; }
35+
bool is_bipartite(int v) { return is_bi[find(v)]; }
4036
};

library/trees/centroid_decomp.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ template<class F, class G> struct centroid {
1818
vi siz;
1919
centroid(const G& adj, F f):
2020
adj(adj), f(f), siz(sz(adj), -1) {
21-
rep(i, 0, sz(adj)) if (siz[i] == -1) dfs(i, -1);
21+
dfs(0, -1);
2222
}
2323
void calc_sz(int v, int p) {
2424
siz[v] = 1;

library/trees/extra_members/compress_tree.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
//! @time O(|subset| log |subset|)
1212
//! @space O(|subset|)
1313
array<vi, 2> compress_tree(vi subset) {
14-
auto proj = [&](int v) { return t[v].in; };
14+
auto proj = [&](int v) { return in[v]; };
1515
ranges::sort(subset, {}, proj);
16-
int siz = sz(subset);
17-
rep(i, 1, siz)
16+
int len = sz(subset);
17+
rep(i, 1, len)
1818
subset.push_back(lca(subset[i - 1], subset[i]));
1919
ranges::sort(subset, {}, proj);
2020
subset.erase(unique(all(subset)), end(subset));
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
int dist_edges(int u, int v) {
2-
return t[u].d + t[v].d - 2 * t[lca(u, v)].d;
1+
int dist(int u, int v) {
2+
return d[u] + d[v] - 2 * d[lca(u, v)];
33
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//! returns 1 if v is in u's subtree
22
bool in_subtree(int u, int v) {
3-
return t[u].in <= t[v].in &&
4-
t[v].in < t[u].in + t[u].sub_sz;
3+
return in[u] <= in[v] && in[v] < in[u] + siz[u];
54
}

library/trees/ladder_decomposition/ladder_decomposition.hpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,36 @@
55
//! @code
66
//! ladder ld(adj);
77
//! // KACTL functions
8-
//! int kth_par = jmp(ld.b_tbl, v, k);
9-
//! int curr_lca = lca(ld.b_tbl, ld.d, u, v);
8+
//! int kth_par = jmp(ld.jmp, v, k);
9+
//! int curr_lca = lca(ld.jmp, ld.d, u, v);
1010
//! @endcode
1111
struct ladder {
1212
int n;
13-
vector<vi> b_tbl;
14-
vi d, p, dl, idx_l, l_tbl;
13+
vi d, p, leaf, idx, lad;
14+
vector<vi> jmp;
1515
//! @param adj forest (rooted or unrooted)
1616
//! @time O(n log n)
17-
//! @space O(n log n) for b_tbl. Everything else is O(n)
17+
//! @space O(n log n) for jmp. Everything else is O(n)
1818
ladder(const auto& adj):
19-
n(sz(adj)), d(n), p(n, -1), dl(n), idx_l(n) {
19+
n(sz(adj)), d(n), p(n), leaf(n), idx(n), lad(2 * n) {
2020
auto dfs = [&](auto&& self, int v) -> void {
21-
dl[v] = v;
21+
leaf[v] = v;
2222
for (int u : adj[v])
2323
if (u != p[v]) {
2424
d[u] = d[p[u] = v] + 1;
2525
self(self, u);
26-
if (d[dl[u]] > d[dl[v]]) dl[v] = dl[u];
26+
if (d[leaf[v]] < d[leaf[u]]) leaf[v] = leaf[u];
2727
}
2828
};
29-
rep(i, 0, n) {
30-
if (p[i] == -1) p[i] = i, dfs(dfs, i);
31-
if (p[i] == i || dl[p[i]] != dl[i]) {
32-
int v = dl[i], len = (d[v] - d[i]) * 2;
33-
idx_l[v] = sz(l_tbl) + d[v];
34-
for (; v != -1 && len--; v = p[v])
35-
l_tbl.push_back(v);
36-
}
29+
dfs(dfs, 0);
30+
int pos = 0;
31+
rep(i, 0, n) if (p[i] == i || leaf[p[i]] != leaf[i]) {
32+
int l = leaf[i];
33+
int len = min((d[l] - d[i]) * 2, d[l] + 1);
34+
idx[l] = pos;
35+
for (; len--; l = p[l]) lad[pos++] = l;
3736
}
38-
b_tbl = treeJump(p);
37+
jmp = treeJump(p);
3938
}
4039
//! @param v query node
4140
//! @param k number of edges
@@ -47,11 +46,11 @@ struct ladder {
4746
assert(0 <= k && k <= d[v]);
4847
if (k == 0) return v;
4948
int bit = __lg(k);
50-
v = b_tbl[bit][v], k -= (1 << bit);
51-
int l = idx_l[dl[v]] - d[v];
52-
assert(l_tbl[l] == v);
53-
// subarray [l, l+k] of l_tbl corresponds to the rest
49+
v = jmp[bit][v], k -= (1 << bit);
50+
int l = idx[leaf[v]] + d[leaf[v]] - d[v];
51+
assert(lad[l] == v);
52+
// subarray [l, l+k] of lad corresponds to the rest
5453
// of the jump
55-
return l_tbl[l + k];
54+
return lad[l + k];
5655
}
5756
};

library/trees/lca_rmq/lca_rmq.hpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,27 @@
1313
//! @space O(nlogn)
1414
// NOLINTNEXTLINE(readability-identifier-naming)
1515
struct LCA {
16-
struct node {
17-
int in, sub_sz = 1, d, p = -1;
18-
};
19-
vector<node> t;
16+
int n;
17+
vi in, siz, d, p;
2018
RMQ<int, function<int(int, int)>> rmq = {{}, NULL};
21-
LCA(const auto& adj): t(sz(adj)) {
19+
LCA(const auto& adj):
20+
n(sz(adj)), in(n), siz(n, 1), d(n), p(n) {
2221
vi order;
2322
auto dfs = [&](auto&& self, int v) -> void {
24-
t[v].in = sz(order), order.push_back(v);
23+
in[v] = sz(order), order.push_back(v);
2524
for (int u : adj[v])
26-
if (u != t[v].p)
27-
t[u].d = t[t[u].p = v].d + 1, self(self, u),
28-
t[v].sub_sz += t[u].sub_sz;
25+
if (u != p[v])
26+
d[u] = d[p[u] = v] + 1, self(self, u),
27+
siz[v] += siz[u];
2928
};
30-
rep(i, 0, sz(t)) if (t[i].p == -1) dfs(dfs, i);
31-
rmq = {order, [&](int u, int v) {
32-
return t[u].d < t[v].d ? u : v;
33-
}};
29+
dfs(dfs, 0);
30+
rmq = {order,
31+
[&](int u, int v) { return d[u] < d[v] ? u : v; }};
3432
}
3533
int lca(int u, int v) {
3634
if (u == v) return u;
37-
auto [x, y] = minmax(t[u].in, t[v].in);
38-
return t[rmq.query(x + 1, y + 1)].p;
35+
auto [x, y] = minmax(in[u], in[v]);
36+
return p[rmq.query(x + 1, y + 1)];
3937
}
4038
#include "../extra_members/dist_edges.hpp"
4139
#include "../extra_members/in_subtree.hpp"

library/trees/lca_rmq/next_on_path.hpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
//! @space O(1)
66
int next_on_path(int u, int v) {
77
assert(u != v);
8-
return in_subtree(u, v)
9-
? rmq.query(t[u].in + 1, t[v].in + 1)
10-
: t[u].p;
8+
return in_subtree(u, v) ? rmq.query(in[u] + 1, in[v] + 1)
9+
: p[u];
1110
}

library/trees/linear_lca.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ struct linear_lca {
4141
}
4242
return d[u] < d[v] ? u : v;
4343
}
44+
#include "extra_members/dist_edges.hpp"
4445
};

library/trees/subtree_isomorphism.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,6 @@ auto subtree_iso(const auto& adj) {
2626
hashes.try_emplace(ch_ids, sz(hashes))
2727
.first->second;
2828
};
29-
rep(i, 0, sz(adj)) if (iso_id[i] == -1) dfs(dfs, i, i);
29+
dfs(dfs, 0, 0);
3030
return pair{sz(hashes), iso_id};
3131
}

0 commit comments

Comments
 (0)