This documentation is automatically generated by competitive-verifier/competitive-verifier
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/lca
#include <bits/stdc++.h>
#define PUSHB push_back
#define ALL(a) (a).begin(), (a).end()
using namespace std;
using ll = long long;
#include "../../src/graph/lca.hpp"
#include "../../src/misc/read.hpp"
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n = read(), q = read();
LCA lca(n);
for (int i = 1; i < n; i++) {
int p = read();
lca.adde(i, p);
}
lca.work(0);
while (q--) {
int u = read(), v = read();
cout << lca.query(u, v) << "\n";
}
return 0;
}
#line 1 "test/graph/lca.test.cpp"
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/lca
#include <bits/stdc++.h>
#define PUSHB push_back
#define ALL(a) (a).begin(), (a).end()
using namespace std;
using ll = long long;
#line 1 "src/graph/lca.hpp"
// 时间复杂度: 预处理 $\mathcal{O}(n \log n)$; 查询 $\mathcal{O}(1)$
struct LCA {
int n, m, cur_dfn = 0;
vector<int> dfn, dep;
vector<vector<int>> G, st;
LCA(int n)
: n(n), m(32 - __builtin_clz(n)), dfn(n, -1), dep(n), G(n),
st(m, vector<int>(n)) {}
void adde(int u, int v) { G[u].PUSHB(v), G[v].PUSHB(u); }
void work(int root) {
dfs(root, root);
for (int j = 1; j < m; j++)
for (int i = 0; i + (1 << j) <= n; i++)
st[j][i] = op4st(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
}
int query(int u, int v) const {
if (u == v) return u;
if ((u = dfn[u]) > (v = dfn[v])) swap(u, v);
int q = __lg(v - u);
return op4st(st[q][u + 1], st[q][v + 1 - (1 << q)]);
}
private:
int op4st(int u, int v) const { return dfn[u] < dfn[v] ? u : v; }
void dfs(int u, int fa_) {
st[0][dfn[u] = cur_dfn++] = fa_;
for (int v : G[u])
if (v != fa_) dep[v] = dep[u] + 1, dfs(v, u);
}
};
#line 1 "src/misc/read.hpp"
#define GC ch = getchar_unlocked()
ll read() {
ll x = 0, f = 1, GC;
while (ch < '0' || ch > '9') ch == '-' ? f = -1, GC : GC;
while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', GC;
return x * f;
}
#undef GC
#line 10 "test/graph/lca.test.cpp"
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n = read(), q = read();
LCA lca(n);
for (int i = 1; i < n; i++) {
int p = read();
lca.adde(i, p);
}
lca.work(0);
while (q--) {
int u = read(), v = read();
cout << lca.query(u, v) << "\n";
}
return 0;
}
| Env | Name | Status | Elapsed | Memory |
|---|---|---|---|---|
| g++ | almost_line_00 |
|
154 ms | 81 MB |
| g++ | almost_line_01 |
|
157 ms | 80 MB |
| g++ | binary_00 |
|
191 ms | 72 MB |
| g++ | binary_01 |
|
181 ms | 72 MB |
| g++ | binary_02 |
|
188 ms | 72 MB |
| g++ | example_00 |
|
5 ms | 4 MB |
| g++ | line_00 |
|
124 ms | 70 MB |
| g++ | line_01 |
|
138 ms | 83 MB |
| g++ | line_02 |
|
52 ms | 12 MB |
| g++ | line_03 |
|
81 ms | 77 MB |
| g++ | line_04 |
|
63 ms | 51 MB |
| g++ | max_line_00 |
|
155 ms | 89 MB |
| g++ | max_line_01 |
|
158 ms | 89 MB |
| g++ | max_line_02 |
|
153 ms | 89 MB |
| g++ | max_random_00 |
|
205 ms | 72 MB |
| g++ | max_random_01 |
|
211 ms | 72 MB |
| g++ | max_random_02 |
|
189 ms | 72 MB |
| g++ | path_graph_root_centroid_00 |
|
133 ms | 80 MB |
| g++ | path_graph_root_centroid_01 |
|
133 ms | 80 MB |
| g++ | path_graph_root_centroid_02 |
|
131 ms | 80 MB |
| g++ | random_00 |
|
135 ms | 57 MB |
| g++ | random_01 |
|
160 ms | 67 MB |
| g++ | random_02 |
|
52 ms | 10 MB |
| g++ | random_03 |
|
110 ms | 63 MB |
| g++ | random_04 |
|
72 ms | 42 MB |