Skip to content

Commit c18a52c

Browse files
committed
concept for reducing the number of operations
1 parent 706fadf commit c18a52c

File tree

2 files changed

+32
-21
lines changed

2 files changed

+32
-21
lines changed

library/trees/linear_lca.hpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,39 +12,50 @@
1212
//! @space O(n)
1313
struct linear_lca {
1414
struct node {
15-
int d, label, asc;
15+
int pos, label, asc;
1616
};
1717
vector<node> t;
1818
vi head;
19-
linear_lca(const auto& adj):
20-
t(sz(adj)), head(sz(t) + 1) {
21-
vector<pii> order;
22-
auto dfs = [&](auto&& self, int v, int p) -> void {
23-
order.emplace_back(v, p);
24-
t[v].label = sz(order);
25-
for (int u : adj[v])
26-
if (u != p) {
27-
t[u].d = 1 + t[v].d;
19+
linear_lca(auto& adj) : t(sz(adj)), head(sz(t) + 1) {
20+
{
21+
int Time = 1;
22+
auto dfs = [&](auto&& self, int v, int p) -> void {
23+
t[v].label = Time++;
24+
for (int& u : adj[v]) {
25+
assert(u != p);
2826
self(self, u, v);
2927
head[t[u].label] = v;
30-
if ((t[u].label & -t[u].label) >
31-
(t[v].label & -t[v].label))
28+
if ((t[u].label & -t[u].label) > (t[v].label & -t[v].label)) {
3229
t[v].label = t[u].label;
30+
swap(u, adj[v][0]);
31+
}
3332
}
34-
};
35-
rep(i, 0, sz(t)) if (t[i].d == 0) dfs(dfs, i, i);
36-
for (auto [v, p] : order)
37-
t[v].asc = t[p].asc | (t[v].label & -t[v].label);
33+
};
34+
dfs(dfs, 0, 0);
35+
}
36+
{
37+
int Time = 0;
38+
auto dfs = [&](auto&& self, int v, int p) -> void {
39+
t[v].asc = t[p].asc | (t[v].label & -t[v].label);
40+
t[v].pos = Time++;
41+
for (int u : adj[v])
42+
if (u != p) {
43+
self(self, u, v);
44+
}
45+
};
46+
dfs(dfs, 0, 0);
47+
}
3848
}
3949
int lca(int u, int v) {
50+
if (t[u].pos > t[v].pos) swap(u, v);
4051
if (unsigned j = t[u].label ^ t[v].label; j) {
4152
j = t[u].asc & t[v].asc & -bit_floor(j);
42-
if (unsigned k = t[u].asc ^ j; k)
43-
k = bit_floor(k), u = head[(t[u].label & -k) | k];
53+
//if (unsigned k = t[u].asc ^ j; k)
54+
//k = bit_floor(k), u = head[(t[u].label & -k) | k];
4455
if (unsigned k = t[v].asc ^ j; k)
4556
k = bit_floor(k), v = head[(t[v].label & -k) | k];
4657
}
47-
return t[u].d < t[v].d ? u : v;
58+
return t[u].pos < t[v].pos ? u : v;
4859
}
49-
#include "extra_members/dist_edges.hpp"
60+
//#include "extra_members/dist_edges.hpp"
5061
};

tests/library_checker_aizu_tests/trees/lca_all_methods_lib_checker.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ int main() {
1717
}
1818
tree_lift tl(adj);
1919
LCA lc(adj);
20-
linear_lca lin_lca(adj);
2120
compress_tree_asserts(adj, lc);
21+
linear_lca lin_lca(adj);
2222
for (int i = 0; i < n; i++) {
2323
assert(tl.lca(i, i) == i);
2424
assert(lc.lca(i, i) == i);

0 commit comments

Comments
 (0)