Pagini recente » Istoria paginii runda/tsa_ojisim2014 | Cod sursa (job #319292) | Cod sursa (job #2494662) | Istoria paginii runda/round_2 | Cod sursa (job #2707380)
#include <bits/stdc++.h>
using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
int n, q;
vector <int> v[100010];
vector <pair <int , int> > euler;
pair <int , int> rmq[20][200001];
int first_ap[100001];
int lgg[100001];
void dfs (int nod, int nivel)
{
euler.push_back({nod, nivel});
for (auto i: v[nod])
{
dfs(i,nivel + 1);
if (v[nod].size())
euler.push_back({nod, nivel});
}
}
void preq ()
{
lgg[1] = 0;
for (int i = 2;i<=100000;++i)
lgg[i] = lgg[i/2] + 1;
for (int i = 1;i<euler.size();++i)
{
rmq[0][i].first = euler[i].second;
rmq[0][i].second = euler[i].first;
}
for (int i = 1;i <= 18;++i)
{
int k = euler.size() - (1<<i);
for (int j = 1; j <= k;++j)
{
if (rmq[i-1][j].first < rmq[i-1][j + (1<<(i-1))].first)
{
rmq[i][j].first = rmq[i-1][j].first;
rmq[i][j].second = rmq[i-1][j].second;
}
else
{
rmq[i][j].first = rmq[i-1][j + (1<<(i-1))].first;
rmq[i][j].second = rmq[i-1][j + (1<<(i-1))].second;
}
}
}
}
int query (int st, int dr)
{
int lv = lgg[dr - st + 1];
if (rmq[lv][st].first < rmq[lv][dr - (1<<lv) + 1].first)
return rmq[lv][st].second;
else
return rmq[lv][dr - (1<<lv) + 1].second;
}
int main ()
{
in >> n >> q;
for (int i = 2;i<=n; ++i)
{
int a;
in >> a;
v[a].push_back(i);
}
euler.push_back({0,0});
dfs(1, 0);
preq();
for (int i = 1;i<euler.size();++i)
if (first_ap[euler[i].first]==0)
first_ap[euler[i].first] = i;
for (int i = 1;i<=q;++i)
{
int a, b;
in >> a >> b;
a = first_ap[a];
b = first_ap[b];
out << query (min (a,b), max(a,b)) << '\n';
}
return 0;
}