Pagini recente » Cod sursa (job #2347269) | Cod sursa (job #3203223) | Cod sursa (job #2900293) | Cod sursa (job #2666873) | Cod sursa (job #3262682)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Lmax = 20;
const int Nmax = 200001;
int n, m, x, y, st, dr;
vector<vector<int>> graf, r;
vector<int> viz, first, d, euler, E;
void dfs(int node, int h)
{
euler.push_back(node);
viz[node] = 1;
d[node] = h;
first[node] = euler.size() - 1;
for(auto next:graf[node])
if(!viz[next])
{
dfs(next, h + 1);
euler.push_back(node);
}
}
void precalc()
{
for(int i=0; i<euler.size(); i++)
r[0][i] = euler[i];
int s = euler.size();
for(int p=1; p < 20; p++)
for(int i=0; i + (1 << p) <= s; i++)
{
int left = r[p-1][i];
int right = r[p-1][i + (1 << (p - 1))];
if(d[left] < d[right])
r[p][i] = left;
else
r[p][i] = right;
}
for(int i=2; i<=s; i++)
E[i] = E[i/2] + 1;
}
int main()
{
cin >> n >> m;
graf.assign(n+1, vector<int>());
d.resize(n+1);
viz.resize(n+1);
first.assign(n+1, -1);
for(int i=2; i<=n; i++)
{
cin >> x;
graf[x].push_back(i);
graf[i].push_back(x);
}
dfs(1, 1);
E.resize(euler.size() + 1);
r.assign(Lmax, vector<int>(euler.size(), 0));
precalc();
while(m--)
{
cin >> st >> dr;
st = first[st];
dr = first[dr];
if(st > dr)
swap(st, dr);
int exp = E[dr - st + 1];
int left = r[exp][st];
int right = r[exp][dr - (1<<exp) + 1];
int ans = 0;
if(d[left] < d[right])
ans = left;
else
ans = right;
cout << ans << '\n';
}
return 0;
}