Pagini recente » Cod sursa (job #3328352) | Cod sursa (job #319804) | Monitorul de evaluare | Cod sursa (job #726328) | Cod sursa (job #3333281)
#include <bits/stdc++.h>
using namespace std;
int main() {
fstream fin("lca.in", ios::in);
fstream fout("lca.out", ios::out);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
fin >> n >> m;
vector<vector<int>> adj(n + 1);
vector<int> par(n + 1, 0);
for (int i = 2; i <= n; ++i) {
int p;
fin >> p;
par[i] = p;
adj[p].push_back(i);
adj[i].push_back(p);
}
int LOG = 1;
while ((1 << LOG) <= n) ++LOG;
vector<vector<int>> up(LOG, vector<int>(n + 1, 0));
vector<int> depth(n + 1, 0);
{
vector<int> st;
st.push_back(1);
up[0][1] = 0;
depth[1] = 0;
vector<int> parent(n + 1, 0);
parent[1] = 0;
while (!st.empty()) {
int u = st.back();
st.pop_back();
for (int v : adj[u]) {
if (v == parent[u]) continue;
parent[v] = u;
up[0][v] = u;
depth[v] = depth[u] + 1;
st.push_back(v);
}
}
}
for (int k = 1; k < LOG; ++k) {
for (int v = 1; v <= n; ++v) {
int mid = up[k - 1][v];
up[k][v] = mid ? up[k - 1][mid] : 0;
}
}
auto lift = [&](int u, int d) {
for (int k = 0; k < LOG; ++k) {
if (d & (1 << k)) u = up[k][u];
}
return u;
};
auto lca = [&](int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
u = lift(u, depth[u] - depth[v]);
if (u == v) return u;
for (int k = LOG - 1; k >= 0; --k) {
if (up[k][u] != up[k][v]) {
u = up[k][u];
v = up[k][v];
}
}
return up[0][u];
};
string out;
out.reserve(m * 3);
for (int i = 0; i < m; ++i) {
int u, v;
fin >> u >> v;
int w = lca(u, v);
out.append(to_string(w));
out.push_back('\n');
}
fout << out;
return 0;
}