Pagini recente » Cod sursa (job #187888) | Cod sursa (job #503988) | Cod sursa (job #2805141) | Cod sursa (job #2522922) | Cod sursa (job #1989601)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int nMax = 100005;
const int logMax = 20;
class arbore
{
public:
arbore(int * father, int n)
{
this->n = n;
for(int i = 0; (1 << (i-1)) <= n; ++i)
this->father[i] = new int[n+1];
for(int i = 1; i <= n; ++i)
{
if(father[i] >= 1)
child[father[i]].push_back(i);
this->father[0][i] = father[i];
}
UpdateFathers();
UpdateNivel();
}
~arbore()
{
delete[] child;
for(int i = 0; (1 << (i-1)) <= n; ++i)
delete[] father[i];
}
int Query(int x, int y)
{
if(nivel[x] < nivel[y])
swap(x, y);
int step;
for(step = 0; (1 << step) < n; ++step);
for(int i = step; i >= 0; --i)
{
if(father[i][x] >= 1 && nivel[father[i][x]] >= nivel[y])
x = father[i][x];
}
if(x == y)
return x;
for(int i = step; i >= 0; --i)
if(father[i][x] != father[i][y])
x = father[i][x], y = father[i][y];
return father[0][x];
}
private:
void UpdateFathers()
{
for(int i = 1; (1 << (i-1)) <= n; ++i)
for(int j = 1; j <= n; ++j)
{
if(father[i-1][j] < 1)
father[i][j] = father[i-1][j];
else
father[i][j] = father[i-1][father[i-1][j]];
}
}
void UpdateNivel(int current = 1, int niv = 1)
{
nivel[current] = niv;
for(auto c:child[current])
UpdateNivel(c, niv + 1);
}
int n;
int nivel[logMax];
int * father[logMax]; //al 2^i-ulea father al lui j
vector<int> child[nMax];
};
int n, m;
int father[nMax];
int main()
{
ifstream in("lca.in");
ofstream out("lca.out");
in >> n >> m;
father[1] = -1;
for(int i = 2; i <= n; ++i)
in >> father[i];
arbore arb(father, n);
int x, y;
for(int i = 1; i <= m; ++i)
{
in >> x >> y;
out << arb.Query(x, y) << "\n";
}
return 0;
}