Pagini recente » igorj_10 | Cod sursa (job #894160) | Cod sursa (job #584323) | Cod sursa (job #2705081) | Cod sursa (job #1404228)
#include <iostream>
#include <fstream>
#include <vector>
#include <stack>
#define nmax 100005
using namespace std;
int n, m;
int Euler[2 * nmax], P[nmax], Exp[2 * nmax], Min[19][2 * nmax], Pos[19][2 * nmax], Nivel[nmax];
vector <int> G[nmax];
void euler(int nod)
{
Euler[++Euler[0]] = nod;
P[nod] = Euler[0];
for (int i = 0; i < G[nod].size(); i++)
{
Nivel[G[nod][i]] = Nivel[nod] + 1;
euler(G[nod][i]);
Euler[++Euler[0]] = nod;
}
}
void preprocess()
{
Exp[1] = 0;
for (int i = 2; i <= Euler[0]; i++)
Exp[i] = Exp[i/2] + 1;
for (int i = 1; i <= Euler[0]; i++)
{
Min[0][i] = Nivel[Euler[i]];
Pos[0][i] = i;
}
for (int i = 1; i <= Exp[Euler[0]]; i++)
for (int j = 1; j <= Euler[0] - (1<<i) + 1; j++)
{
int st = j;
int dr = st + (1<<i) - 1;
int mid = dr - (1<<(i-1)) + 1;
Min[i][j] = Min[i-1][st];
Pos[i][j] = Pos[i-1][st];
if (Min[i][j] > Min[i-1][mid])
{
Min[i][j] = Min[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++)
{
int x;
fi >> x;
G[x].push_back(i);
}
euler(1);
preprocess();
for (int i = 1; i <= m; i++)
{
int x, y;
fi >> x >> y;
x = P[x], y = P[y];
if (x > y)
swap(x, y);
int l = y - x + 1;
int k = Exp[l];
int rez = Min[k][x];
int lca = Euler[Pos[k][x]];
x = y - (1<<k) + 1;
if (rez > Min[k][x])
lca = Euler[Pos[k][x]];
fo << lca << "\n";
}
fi.close();
fo.close();
return 0;
}
// 3 2 1 2 2