Pagini recente » Cod sursa (job #435918) | Cod sursa (job #3162197) | Cod sursa (job #172993) | Cod sursa (job #2741312) | Cod sursa (job #2855564)
#include <iostream>
#include <fstream>
#include <vector>
#include <set>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX = 100010;
int N, M, t[NMAX];
set <int> f[NMAX];
vector <int> euler, levi;
vector <int> rmq[18];
int a[NMAX], p;
void gen(int val, int lv)
{
euler.push_back(val);
levi.push_back(lv);
a[val] = p++;
for (auto i : f[val]) {
gen(i, lv + 1);
euler.push_back(val);
levi.push_back(lv);
p++;
}
}
int grad = 1;
void genrmq()
{
int j = 1 << grad;
for (int i = 0; i + j <= p; i++)
rmq[grad].push_back(levi[rmq[grad - 1][i]] < levi[rmq[grad - 1][i + (j >> 1)]] ? rmq[grad - 1][i] : rmq[grad - 1][i + (j >> 1)]);
if (1 << ++grad <= p)
genrmq();
}
int main()
{
ios_base::sync_with_stdio(false);
int x, y;
fin >> N >> M;
for (int i = 2; i <= N; i++)
{
fin >> t[i];
f[t[i]].insert(i);
}
gen(1, 0);
for (int i = 0; i < euler.size(); i++)
rmq[0].push_back(i);
genrmq()
grad--;
int j, k;
for (int i = 0; i < M; i++)
{
fin >> x >> y;
if (x == y)
fout << x << "\n";
else
{
if (a[x] > a[y])
swap(x, y);
j = 1 << grad;
k = grad;
while (a[y] - a[x] < j && k) {
j >>= 1;
k--;
}
if (j == a[y] - a[x])
fout << euler[rmq[k][a[x]]] << "\n";
else
fout << euler[(levi[rmq[k][a[x]]] < levi[rmq[k][a[y] - j]] ? rmq[k][a[x]] : rmq[k][a[y] - j])] << "\n";
}
}
return 0;
}