Pagini recente » Borderou de evaluare (job #2013166) | Cod sursa (job #172704) | Cod sursa (job #3264264) | Cod sursa (job #1717301) | Cod sursa (job #2737723)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int maxn = 100005;
vector <int> v[maxn];
vector <int> euler;
int aint[maxn * 8];
int firstap[maxn];
int nivel[maxn];
void dfs(int nod, int niv)
{
nivel[nod] = niv;
euler.push_back(nod);
for(auto it : v[nod])
{
dfs(it, niv + 1);
euler.push_back(nod);
}
}
void update(int nod, int st, int dr, int poz, int val)
{
if(poz < st || poz > dr)
return;
if(st == dr)
{
aint[nod] = val;
return;
}
int mij = (st + dr) / 2;
update(nod * 2, st, mij, poz, val);
update(nod * 2 + 1, mij + 1, dr, poz, val);
if(nivel[aint[nod * 2]] < nivel[aint[nod * 2 + 1]])
aint[nod] = aint[nod * 2];
else
aint[nod] = aint[nod * 2 + 1];
}
int query(int nod, int st, int dr, int x, int y)
{
if(st > y || dr < x)
return 0;
if(x <= st && dr <= y)
return aint[nod];
int mij = (st + dr) / 2;
int q1 = query(nod * 2, st, mij, x, y);
int q2 = query(nod * 2 + 1, mij + 1, dr, x, y);
if(nivel[q1] < nivel[q2])
return q1;
else
return q2;
}
int main()
{
int n, m;
in >> n >> m;
for(int i = 2; i <= n; i++)
{
int x;
in >> x;
v[x].push_back(i);
}
dfs(1, 0);
int poz = 0;
for(auto it : euler)
{
update(1, 1, n * 2 - 1, ++poz, it);
if(firstap[it] == 0)
firstap[it] = poz;
}
nivel[0] = (1 << 30);
for(int i = 1; i <= m; i++)
{
int x, y;
in >> x >> y;
x = firstap[x];
y = firstap[y];
out << query(1, 1, n * 2 - 1, min(x, y), max(x, y)) << "\n";
}
return 0;
}