|
12 | 12 | //! @space O(n) |
13 | 13 | struct linear_lca { |
14 | 14 | struct node { |
15 | | - int d, label, asc; |
| 15 | + int pos, label, asc; |
16 | 16 | }; |
17 | 17 | vector<node> t; |
18 | 18 | 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); |
28 | 26 | self(self, u, v); |
29 | 27 | 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)) { |
32 | 29 | t[v].label = t[u].label; |
| 30 | + swap(u, adj[v][0]); |
| 31 | + } |
33 | 32 | } |
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 | + } |
38 | 48 | } |
39 | 49 | int lca(int u, int v) { |
| 50 | + if (t[u].pos > t[v].pos) swap(u, v); |
40 | 51 | if (unsigned j = t[u].label ^ t[v].label; j) { |
41 | 52 | 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]; |
44 | 55 | if (unsigned k = t[v].asc ^ j; k) |
45 | 56 | k = bit_floor(k), v = head[(t[v].label & -k) | k]; |
46 | 57 | } |
47 | | - return t[u].d < t[v].d ? u : v; |
| 58 | + return t[u].pos < t[v].pos ? u : v; |
48 | 59 | } |
49 | | -#include "extra_members/dist_edges.hpp" |
| 60 | +//#include "extra_members/dist_edges.hpp" |
50 | 61 | }; |
0 commit comments