-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLCA.code-snippets
97 lines (97 loc) · 2.97 KB
/
LCA.code-snippets
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
{
"LCA": {
"prefix": "LCA",
"body": [
"template < typename T = int > struct LCA {",
" ",
" struct Edge {",
"",
" ll v, w;",
"",
" Edge(ll V = 0, ll W = 0) : v(V), w(W) {}",
"",
" bool operator < (const Edge &rhs) const {",
" return w < rhs.w;",
" }",
"",
" };",
"",
" int N, LOG;",
" vector < vector < T > > anc, cost;",
" vector < vector < Edge > > adj;",
" vector < int > dep;",
" ",
" LCA(int n){",
" N = n + 10, LOG = 0;",
" while((1 << LOG) <= n) LOG++;",
" dep = vector < int > (N);",
" adj = vector < vector < Edge > > (N);",
" anc = cost = vector < vector < T > > (N, vector < T > (LOG));",
" }",
" ",
" void add_edge(int u, int v, T w){",
" adj[u].push_back(Edge(v, w));",
" adj[v].push_back(Edge(u, w));",
" }",
"",
" void build_adj(int edges){",
" for(int i = 0, u, v, w; i < edges && cin >> u >> v >> w; i++)",
" add_edge(u, v, w);",
" }",
"",
" T operation(T a, T b){",
" return a + b;",
" }",
" ",
" void dfs(int u, int p = 0){",
" for(auto& [v, w] : adj[u]){",
" if(v == p) continue;",
" dep[v] = dep[u] + 1, anc[v][0] = u, cost[v][0] = w;",
" for(int bit = 1; bit < LOG; bit++){",
" anc[v][bit] = anc[anc[v][bit - 1]][bit - 1];",
" cost[v][bit] = operation(cost[v][bit - 1], cost[anc[v][bit - 1]][bit - 1]);",
" }",
" dfs(v, u);",
" }",
" }",
" ",
" int kth_ancestor(int u, int k){",
" if(dep[u] < k) ",
" return -1;",
" for(int bit = LOG - 1; bit >= 0; bit--)",
" if(k & (1 << bit))",
" u = anc[u][bit];",
" return u;",
" }",
" ",
" int get_lca(int u, int v){",
" if(dep[u] < dep[v])",
" swap(u, v);",
" u = kth_ancestor(u, dep[u] - dep[v]);",
" if(u == v)",
" return u;",
" for(int bit = LOG - 1; bit >= 0; bit--)",
" if(anc[u][bit] != anc[v][bit])",
" u = anc[u][bit], v = anc[v][bit];",
" return anc[u][0];",
" }",
" ",
" T get_cost(int u, int dist){",
" if(dep[u] < dist) return -1;",
" T ans = 0;",
" for(int bit = 0; bit < LOG; bit++)",
" if(dist & (1 << bit))",
" ans = operation(ans, cost[u][bit]), u = anc[u][bit];",
" return ans;",
" }",
" ",
" T query(int u, int v){",
" int lca = get_lca(u, v);",
" return operation(get_cost(u, dep[u] - dep[lca]), get_cost(v, dep[v] - dep[lca]));",
" }",
"",
"};"
],
"description": "LCA"
}
}