Pagini recente » Cod sursa (job #1958869) | Cod sursa (job #831587) | Istoria paginii utilizator/barosanunumberone | Cod sursa (job #1616637) | Cod sursa (job #1522549)
#include <fstream>
#include <vector>
#define N_Max 100010
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m, k, Euler[N_Max << 1], Level[N_Max << 1], First_Position[N_Max], Log[N_Max << 1], Rmq[20][N_Max << 1];
vector < int > G[N_Max];
void READ_DATA()
{
fin >> n >> m;
for (int i = 2, dad; i <= n; i ++)
{
fin >> dad;
G[dad].push_back(i);
}
}
void DFS(int nod, int adancime)
{
k ++;
Euler[k] = nod; /// adaug nodul actual in reprezentarea Euler a arborelui
Level[k] = adancime; /// adaug adancimea actuala a nodului in reprezentarea Euler a arborelui
First_Position[nod] = k; /// prima aparitie a nodului actual
for (vector < int > :: iterator it = G[nod].begin(); it != G[nod].end(); it ++)
{
DFS(*it, adancime + 1);
k ++;
Euler[k] = nod;
Level[k] = adancime;
}
}
void RMQ()
{
for (int i = 2; i <= k; i ++) Log[i] = Log[i / 2] + 1;
for (int i = 1; i <= k; i ++) Rmq[0][i] = i;
for (int i = 1; i <= Log[k]; i ++)
{
for (int j = 1; j <= k - (1 << i) + 1; j ++)
{
int l = (1 << (i - 1));
Rmq[i][j] = Rmq[i - 1][j];
if (Level[Rmq[i - 1][j + l]] < Level[Rmq[i][j]])
{
Rmq[i][j] = Rmq[i - 1][j + l];
}
}
}
}
void SOLVE_LCA()
{
for (int i = 1, x, y, lin, sol; i <= m; i ++)
{
fin >> x >> y;
x = First_Position[x];
y = First_Position[y];
if (x > y) swap(x, y);
lin = Log[y - x + 1];
sol = Rmq[lin][x];
if (Level[Rmq[lin][y - (1 << lin) + 1]] < Level[sol])
{
sol = Rmq[lin][y - (1 << lin) + 1];
}
fout << Euler[sol] << '\n';
}
}
int main()
{
READ_DATA();
DFS(1, 0);
RMQ();
SOLVE_LCA();
return 0;
}