Pagini recente » Cod sursa (job #2760628) | Cod sursa (job #11975) | Cod sursa (job #582636) | Cod sursa (job #331893) | Cod sursa (job #1790442)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int Nmax = 100002;
vector<vector<int>> G;
int n, m, nr, x, y;
int a[2*Nmax], lg[2*Nmax], niv[2*Nmax], fp[Nmax], r[2*Nmax][20];
void Read();
void Dfs(int x, int nv);
void Rmq();
int Lca(int x, int y);
int main()
{
Read();
for(int i = 2; i < 2 * Nmax; i++)
lg[i] = lg[i / 2] + 1;
Dfs(1, 1);
Rmq();
for(int i = 1; i <= m; i++)
{
fin >> x >> y;
fout << Lca(x, y) << "\n";
}
fin.close();
fout.close();
return 0;
}
void Read()
{
fin >> n >> m;
G = vector<vector<int>>(n+1);
for (int i = 2; i <= n; i++)
{
fin >> x;
G[x].push_back(i);
}
}
void Dfs(int x, int nv)
{
a[++nr] = x;
niv[nr] = nv;
fp[x] = nr;
for (auto y : G[x])
{
Dfs(y, nv + 1);
a[++nr] = x;
niv[nr] = nv;
}
}
void Rmq()
{
int N = 2 * n - 1;
for (int i = 1; i <= N; i++)
r[i][0] = i;
for(int j = 1; (1 << j) <= N; j++)
for(int i = 1; i + (1 << j) < N; i++)
{
if ( niv[r[i][j - 1]] < niv[r[i + (1 << (j - 1))][j - 1]] )
r[i][j] = r[i][j - 1];
else
r[i][j] = r[i + (1 << (j - 1))][j - 1];
}
}
int Lca(int x, int y)
{
int px = fp[x], py = fp[y];
if ( px > py )
swap(px, py);
int k = lg[py - px + 1];
if ( niv[r[px][k]] < niv[r[py - (1 << k) + 1][k]])
return a[r[px][k]];
return a[r[py - (1 << k) + 1][k]];
}