Pagini recente » Cod sursa (job #1461353) | Cod sursa (job #2001769) | Cod sursa (job #1503695) | Istoria paginii runda/ichc_preoji2010 | Cod sursa (job #2953556)
#include <bits/stdc++.h>
#define NMAX 100008
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m, x, L, timer, level;
vector <int> G[NMAX];
int tin[NMAX], tout[NMAX], up[NMAX][20], lvl[NMAX], logg[NMAX];
void DFS(int nod, int tata, int level);
int LCA(int u, int v);
bool stramos(int u, int v);
int main()
{
fin >> n >> m;
logg[1] = 0;
for (int i = 2; i <= n; i++)
logg[i] = logg[i/2] + 1;
for (int i = 2; i <= n; i++)
{
fin >> x;
G[x].push_back(i);
}
L = (int)(log2(n));
DFS(1, 0, 0);
int u, v;
for (int i = 1; i <= m; i++)
{
fin >> u >> v;
fout << LCA(u, v) << '\n';
}
return 0;
}
void DFS(int nod, int tata, int level)
{
tin[nod] = ++timer;
lvl[nod] = level;
up[nod][0] = tata;
for (int i = 1; i <= L; i++)
up[nod][i] = up[up[nod][i-1]][i-1];
for (auto el : G[nod])
DFS(el, nod, level+1);
tout[nod] = ++timer;
}
bool stramos(int u, int v)
{
if (u == 0)
return 1;
return (tin[u] <= tin[v] && tout[v] <= tout[u]);
}
int LCA(int u, int v)
{
if (stramos(u, v))
return u;
if (stramos(v, u))
return v;
for (int i = logg[lvl[u]]; i >= 0; i--)
if (!stramos(up[u][i], v))
u = up[u][i];
return up[u][0];
}