Pagini recente » Cod sursa (job #1252675) | Cod sursa (job #1055133) | Cod sursa (job #3145770) | Cod sursa (job #2063253) | Cod sursa (job #2874120)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int NMAX = 1e5+5, LMAX = 18;
vector<int> euler, g[NMAX];
int invers[NMAX], depth[NMAX];
void liniarizare(int node, int father, int cnt_depth)
{
depth[node] = cnt_depth;
euler.push_back(node);
for(auto son: g[node])
{
if(son == father)
continue;
liniarizare(son, node, cnt_depth + 1);
euler.push_back(node);
}
}
int rmq[LMAX][1 << LMAX];
void init_rmq()
{
depth[0] = NMAX;
for(int i = 0; i < euler.size(); i++)
{
rmq[0][i] = euler[i];
invers[euler[i]] = i;
}
for(int level = 1; level < LMAX; level++)
for(int i = 0; i + (1 << level) / 2 < euler.size(); i++)
{
int a = rmq[level - 1][i];
int b = rmq[level - 1][i + (1 << level) / 2];
if(depth[a] > depth[b])
rmq[level][i] = b;
else
rmq[level][i] = a;
}
}
int query_rmq(int a, int b)
{
int posa = invers[a];
int posb = invers[b];
if(posa > posb)
swap(posa, posb);
if(posa == posb)
return rmq[0][posa];
int length = posb - posa;
int lg = 31 - __builtin_clz(length);
a = rmq[lg][posa];
b = rmq[lg][posb - (1 << lg)];
if(depth[a] > depth[b])
return b;
return a;
}
int main()
{
int n, m;
fin >> n >> m;
for(int i = 2; i <= n; i++)
{
int x;
fin >> x;
g[x].push_back(i);
}
liniarizare(1, -1, 1);
init_rmq();
while(m--)
{
int a, b;
fin >> a >> b;
fout << query_rmq(a, b) << '\n';
}
return 0;
}