Pagini recente » Cod sursa (job #485145) | Cod sursa (job #502601) | Cod sursa (job #2295116) | Cod sursa (job #2120931) | Cod sursa (job #1547363)
#include <iostream>
#include <fstream>
#include <vector>
#define nmax 100001
using namespace std;
int n, m;
int x, y;
int RMQ[18][2*nmax], POS[18][2*nmax];
int Euler[2*nmax], Exp[2*nmax];
int Nivel[nmax], T[nmax], firstS[nmax];
vector <int> arb[nmax];
void buildEuler(int nod, int niv)
{
Euler[++Euler[0]] = nod;
Nivel[nod] = niv; // The level of the 'Euler[0]'th node
firstS[nod] = Euler[0]; // first appearance of node 'nod' in the Euler sequence
for (int i = 0; i < arb[nod].size(); i++)
buildEuler(arb[nod][i], niv + 1),
Euler[++Euler[0]] = nod;
}
void preProcess()
{
Exp[1] = 0;
for (int i = 2; i <= Euler[0]; i++)
Exp[i] = 1 + Exp[i/2];
for (int i = 1; i <= Euler[0]; i++)
RMQ[0][i] = Nivel[Euler[i]],
POS[0][i] = i; // The position of node 'Euler[i]' in the Euler sequence
for (int i = 1; i <= Exp[Euler[0]]; i++)
for (int j = 1; j <= Euler[0]; j++)
{
int st = j;
int dr = j + (1<<i) - 1;
int mid = dr - (1<<(i-1)) + 1;
if (RMQ[i-1][st] < RMQ[i-1][mid])
{
RMQ[i][j] = RMQ[i-1][st];
POS[i][j] = POS[i-1][st];
}
else
{
RMQ[i][j] = RMQ[i-1][mid];
POS[i][j] = POS[i-1][mid];
}
}
}
int main()
{
ifstream fi("lca.in");
ofstream fo("lca.out");
fi >> n >> m;
for (int i = 2; i <= n; i++)
fi >> T[i], // lista de tati a arborelui
arb[T[i]].push_back(i);
buildEuler(1, 0);
preProcess();
for (int i = 1; i <= m; i++)
{
fi >> x >> y;
if (x > y)
swap(x, y);
int len = (y - x + 1);
int p = Exp[len];
int mid = y - (1<<p) + 1;
int ancestor = RMQ[p][x];
int posAncestor = POS[p][x];
if (RMQ[p][mid] < ancestor)
posAncestor = POS[p][mid];
fo << Euler[posAncestor] << "\n";
}
fi.close();
fo.close();
return 0;
}