Mai intai trebuie sa te autentifici.
Cod sursa(job #2731143)
Utilizator | Data | 27 martie 2021 13:08:13 | |
---|---|---|---|
Problema | Lowest Common Ancestor | Scor | 70 |
Compilator | cpp-64 | Status | done |
Runda | Arhiva educationala | Marime | 1.92 kb |
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const int N = (int) 2e5 + 7;
int n;
int p[N];
int dep[N];
int euler_tour[2 * N];
int tour_sz;
int first_time_on_tour[N];
int last_time_on_tour[N];
int lg2[2 * N];
vector<int> g[N];
int best(int i, int j) {
if (dep[i] < dep[j]) return i;
return j;
}
int t[4 * 2 * N];
void build(int v, int tl, int tr) {
if (tl == tr) {
t[v] = euler_tour[tl];
} else {
int tm = (tl + tr) / 2;
build(2 * v, tl, tm);
build(2 * v + 1, tm + 1, tr);
t[v] = best(t[2 * v], t[2 * v + 1]);
}
}
int get(int v, int tl, int tr, int l, int r) {
if (l <= tl && tr <= r) {
return t[v];
}
int tm = (tl + tr) / 2;
if (r <= tm) return get(2 * v, tl, tm, l, r);
if (tm + 1 <= l) return get(2 * v + 1, tm + 1, tr, l, r);
return best(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));
}
int get(int l, int r) {
return get(1, 1, tour_sz, l, r);
}
void dfs_lca(int a) {
euler_tour[++tour_sz] = a;
first_time_on_tour[a] = last_time_on_tour[a] = tour_sz;
for (auto &b : g[a]) {
dep[b] = 1 + dep[a];
dfs_lca(b);
euler_tour[++tour_sz] = a;
last_time_on_tour[a] = tour_sz;
}
}
void lcaTM_MihneaAndreescuIntaiDeLaBucuresti() {
dfs_lca(1);
for (int i = 2; i <= tour_sz; i++) {
lg2[i] = 1 + lg2[i / 2];
}
build(1, 1, tour_sz);
}
int lca(int a, int b) {
if (first_time_on_tour[a] > last_time_on_tour[b]) {
swap(a, b);
}
return get(first_time_on_tour[a], last_time_on_tour[b]);
}
int main() {
freopen ("lca.in", "r", stdin);
freopen ("lca.out", "w", stdout);
scanf("%d", &n);
int q;
scanf("%d", &q);
for (int i = 2; i <= n; i++) {
scanf("%d", &p[i]);
g[p[i]].push_back(i);
}
lcaTM_MihneaAndreescuIntaiDeLaBucuresti();
while (q--) {
int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", lca(a, b));
}
}