Pagini recente » Cod sursa (job #2408818) | Cod sursa (job #1515178) | Cod sursa (job #2336876) | Cod sursa (job #2176532) | Cod sursa (job #2648591)
#include <bits/stdc++.h>
using namespace std;
const int N = (int) 2e5 + 7;
const int K = 19;
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];
pair<int, int> tab_lca[2 * N][K];
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()
{
dfs_lca(1);
for (int i = 2; i <= tour_sz; i++)
{
lg2[i] = 1 + lg2[i / 2];
}
for (int i = 1; i <= tour_sz; i++)
{
tab_lca[i][0] = {dep[euler_tour[i]], euler_tour[i]};
}
for (int k = 1; (1 << k) <= tour_sz; k++)
{
for (int i = 1; i + (1 << k) - 1 <= tour_sz; i++)
{
tab_lca[i][k] = min(tab_lca[i][k - 1], tab_lca[i + (1 << (k - 1))][k - 1]);
}
}
}
int lca(int a, int b)
{
if (first_time_on_tour[a] > last_time_on_tour[b])
{
swap(a, b);
}
a = first_time_on_tour[a];
b = last_time_on_tour[b];
int k = lg2[b - a + 1];
return min(tab_lca[a][k], tab_lca[b - (1 << k) + 1][k]).second;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
freopen ("lca.in", "r", stdin);
freopen ("lca.out", "w", stdout);
cin >> n; int q; cin >> q;
for (int i = 2; i <= n; i++)
{
cin>> p[i];
g[p[i]].push_back(i);
}
lcaTM();
while (q--)
{
int a, b;
cin >> a >> b;
cout << lca(a, b) << "\n";
}
}
/// to do : compute Lowest common ancestor