Pagini recente » Cod sursa (job #274387) | Cod sursa (job #743234) | Cod sursa (job #1008917) | Cod sursa (job #3216421) | Cod sursa (job #3265317)
#include <bits/stdc++.h>
#define cin ci
#define cout co
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Lmax = 20;
int n, m, x, y;
vector<vector<int>> anc, graf;
vector<int> viz, d;
void binarylifting()
{
for(int l=1; l<Lmax; l++)
for(int node = 1; node <= n; node++)
anc[l][node] = anc[l-1][anc[l-1][node]];
}
void dfs(int node)
{
viz[node] = 1;
for(auto next:graf[node])
if(!viz[next])
{
d[next] = d[node] + 1;
dfs(next);
}
}
int findanc(int node, int nanc)
{
for(int l=0; l<Lmax; l++)
if(nanc & (1 << l))
node = anc[l][node];
return node;
}
int lca(int node1, int node2)
{
if(d[node1] < d[node2])
swap(node1, node2);
node1 = findanc(node1, d[node1] - d[node2]);
if(node1 == node2)
return node1;
for(int l = Lmax - 1; l>=0; l--)
if(anc[l][node1] != anc[l][node2])
{
node1 = anc[l][node1];
node2 = anc[l][node2];
}
return anc[0][node1];
}
int main()
{
cin >> n >> m;
anc.assign(Lmax + 1, vector<int>(n+1, 0));
graf.assign(n+1, vector<int>());
d.resize(n+1);
viz.resize(n+1);
for(int i=2; i<=n; i++)
{
cin >> anc[0][i];
graf[anc[0][i]].push_back(i);
graf[i].push_back(anc[0][i]);
}
dfs(1);
binarylifting();
while(m--)
{
cin >> x >> y;
cout << lca(x, y) << '\n';
}
return 0;
}