Skip to content

Commit 14a430a

Browse files
committed
no longer have node structs
1 parent c824a46 commit 14a430a

File tree

8 files changed

+48
-77
lines changed

8 files changed

+48
-77
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/extra_members/compress_tree.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
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);
1616
int siz = sz(subset);
1717
rep(i, 1, siz)
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/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/tree_lift/kth_path.hpp

Lines changed: 0 additions & 13 deletions
This file was deleted.

library/trees/tree_lift/tree_lift.hpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,34 @@
77
//! }
88
//! vector<basic_string<int>> adj(n);
99
//! tree_lift tree_l(adj);
10-
//! int kth_p = tree_l.kth_par(v, k);
10+
//! tree_l.kth_par(v, k); // k edges up from v
1111
//! @endcode
12-
//! kth_p = a node k edges up from v
1312
//! @time O(n + q log n)
1413
//! @space O(n)
1514
struct tree_lift {
16-
struct node {
17-
int d, p = -1, j = -1;
18-
};
19-
vector<node> t;
20-
tree_lift(const auto& adj): t(sz(adj)) {
15+
vi d, p, j;
16+
tree_lift(const auto& adj): d(sz(adj)), p(d), j(d) {
2117
auto dfs = [&](auto&& self, int v) -> void {
22-
int jump =
23-
(t[v].d + t[t[t[v].j].j].d == 2 * t[t[v].j].d)
24-
? t[t[v].j].j
25-
: v;
18+
int up =
19+
d[v] + d[j[j[v]]] == 2 * d[j[v]] ? j[j[v]] : v;
2620
for (int u : adj[v])
27-
if (u != t[v].p)
28-
t[u].d = t[t[u].p = v].d + 1, t[u].j = jump,
29-
self(self, u);
21+
if (u != p[v])
22+
d[u] = d[p[u] = v] + 1, j[u] = up, self(self, u);
3023
};
31-
rep(i, 0, sz(t)) if (t[i].j == -1) t[i].j = i,
32-
dfs(dfs, i);
24+
dfs(dfs, 0);
3325
}
3426
int kth_par(int v, int k) {
35-
int anc_d = t[v].d - k;
36-
while (t[v].d > anc_d)
37-
v = t[t[v].j].d >= anc_d ? t[v].j : t[v].p;
27+
int anc_d = d[v] - k;
28+
while (d[v] > anc_d)
29+
v = d[j[v]] >= anc_d ? j[v] : p[v];
3830
return v;
3931
}
4032
int lca(int u, int v) {
41-
if (t[u].d < t[v].d) swap(u, v);
42-
u = kth_par(u, t[u].d - t[v].d);
33+
if (d[u] < d[v]) swap(u, v);
34+
u = kth_par(u, d[u] - d[v]);
4335
while (u != v)
44-
if (t[u].j != t[v].j) u = t[u].j, v = t[v].j;
45-
else u = t[u].p, v = t[v].p;
36+
if (j[u] != j[v]) u = j[u], v = j[v];
37+
else u = p[u], v = p[v];
4638
return u;
4739
}
4840
#include "../extra_members/dist_edges.hpp"

0 commit comments

Comments
 (0)