Pagini recente » Istoria paginii runda/infoexpet/clasament | Istoria paginii runda/chestii/clasament | Istoria paginii runda/rar21 | Monitorul de evaluare | Cod sursa (job #3293228)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Nmax = 1e5 + 5, Lmax = 18;
int parent[Nmax], depth[Nmax], blift[Lmax][Nmax];
vector<int> g[Nmax];
int n;
void dfs(int nod, int par)
{
depth[nod] = depth[par] + 1;
for (auto it : g[nod])
if (it != par)
dfs(it, nod);
}
void binarylift()
{
for (int i = 1; i <= n; i++)
blift[0][i] = parent[i];
for (int j = 1; j < Lmax; j++)
for (int i = 1; i <= n; i++)
blift[j][i] = blift[j - 1][blift[j - 1][i]];
}
int lca(int a, int b)
{
if (depth[a] > depth[b])
swap(a, b);//b e mai adanc, il aduc la depthul lui a
int dif = depth[b] - depth[a];
for (int j = Lmax - 1; j >= 0; j--)
if (dif & (1 << j))
b = blift[j][b];
if (a == b)
return a;
for (int j = Lmax - 1; j >= 0; j--)
if (blift[j][a] != blift[j][b])
a = blift[j][a], b = blift[j][b];
return parent[a];
}
int main()
{
int m, a, b;
cin >> n >> m;
for (int i = 2; i <= n; i++)
{
cin >> parent[i];
g[i].push_back(parent[i]);
g[parent[i]].push_back(i);
}
dfs(1, 0);
binarylift();
while (m--)
{
cin >> a >> b;
cout << lca(a, b) << '\n';
}
}