Pagini recente » Cod sursa (job #2216384) | Cod sursa (job #369739) | Cod sursa (job #3280038) | Cod sursa (job #2258593) | Cod sursa (job #1898786)
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100005
#define LOGMAX 18
using namespace std;
ifstream f ("lca.in");
ofstream g ("lca.out");
vector <int> G[NMAX];
int LOG[NMAX], H[2 * NMAX], LVL[NMAX / 2], FIRST[NMAX], RMQ[NMAX * 2][LOGMAX], k, n, m; // k = Maxim dupa scrierea lui euler
void dfs(int nod, int lvl)
{
H[++k] = nod;
LVL[k] =lvl;
FIRST[nod] = k;
for (unsigned i = 0; i < G[nod].size(); i++)
{
dfs(G[nod][i], lvl + 1);
H[++k] = nod;
LVL[k] = lvl;
}
}
void rmq()
{
for (int i = 1; i <= k; i++)
RMQ[i][0] = i;
for (int i = 1; (1<<i) < k; i++)
{
for (int j = 1; j + (1 << i) <= k; j++)
{
int l = (1 << (i - 1));
RMQ[j][i] = RMQ[j][i - 1];
if (LVL[RMQ[j + l][i - 1]] < LVL[RMQ[j][i]])
RMQ[j][i] = RMQ[j + l][i - 1];
}
}
}
int lca(int x, int y)
{
int dif, l, sol, sh;
int a = FIRST[x], b = FIRST[y];
if (a > b)
swap(a, b);
dif = b - a + 1;
l = LOG[dif];
sol = RMQ[a][l];
sh = dif - (1 << l);
if (LVL[sol] > LVL[RMQ[a + sh][l]])
sol = RMQ[a + sh][l];
return H[sol];
}
int main()
{
f>>n>>m;
for (int x, i = 2; i <= n; i++)
{
f>>x;
G[x].push_back(i);
}
dfs(1, 0);
for (int i = 2; i <= k; i++)
LOG[i] = LOG[i / 2] + 1;
rmq();
while (m--)
{
int x, y;
f>>x>>y;
g<<lca(x, y)<<'\n';
}
return 0;
}