Pagini recente » Statistici Vlad Proteasa (vlad.proteasa) | Rating Gordon Freeman (Gordon) | Cod sursa (job #1057409) | Algoritmiada 2009 - Clasament general, Clasele 9-10 | Cod sursa (job #2970853)
/*
* O(NlogN + QlogN)
*/
#include <fstream>
#include <vector>
using namespace std;
const int MAX_LOG = 18;
const int MAX_N = 100005;
int N, Q;
vector<int> arbore[MAX_N];
int parinte[MAX_N], nivel[MAX_N];
int p_curent, p_start[MAX_N], p_end[MAX_N];
int stramos[MAX_LOG][MAX_N];
void dfs(int nod, int nvl = 1)
{
nivel[nod] = nvl;
p_start[nod] = ++p_curent;
for (int fiu : arbore[nod])
{
dfs(fiu, nvl + 1);
}
p_end[nod] = ++p_curent;
}
bool este_stramos(int x, int y)
{
// return true <=> x este stramos al lui y
return p_start[x] <= p_start[y] && p_end[y] <= p_end[x];
}
void calculeaza_stramosi()
{
for (int nod = 1; nod <= N; ++nod)
{
stramos[0][nod] = parinte[nod];
}
for (int p = 1; p < MAX_LOG; ++p)
{
for (int nod = 1; nod <= N; ++nod)
{
stramos[p][nod] = stramos[p - 1][stramos[p - 1][nod]];
}
}
}
int lca(int x, int y)
{
if (este_stramos(x, y))
{
return x;
}
if (este_stramos(y, x))
{
return y;
}
for (int p = MAX_LOG - 1; p >= 0; --p)
{
int z = stramos[p][x];
if (z != 0 && !este_stramos(z, y))
{
x = z;
}
}
return stramos[0][x];
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> N >> Q;
for (int nod = 2; nod <= N; ++nod)
{
fin >> parinte[nod];
arbore[parinte[nod]].push_back(nod);
}
p_curent = 0;
dfs(1);
calculeaza_stramosi();
while (Q--)
{
int x, y;
fin >> x >> y;
fout << lca(x, y) << "\n";
}
return 0;
}