Pagini recente » Cod sursa (job #2202314) | Cod sursa (job #32264) | Cod sursa (job #1884576) | Cod sursa (job #726192) | Cod sursa (job #1566966)
#include <iostream>
#include <cstdio>
#include <vector>
#define MAXN 100100
#define MAXLOG 20
using namespace std;
vector<int> arb[MAXN];
int n, m, t[MAXN], viz[MAXN], rm[MAXLOG][MAXN], log[2*MAXN];
int k;
vector<int> euler;
vector<int> depth;
void citire()
{
scanf("%d %d", &n, &m);
for (int i = 2; i <= n; i++) {
scanf("%d", &t[i]);
arb[t[i]].push_back(i);
}
depth.push_back(-1);
euler.push_back(-1);
}
void prepareEuler(int crt, int nivel)
{
if (!viz[crt])
viz[crt] = depth.size();
depth.push_back(nivel);
euler.push_back(crt);
for (int i = 0, sz = arb[crt].size(); i < sz; i++) {
prepareEuler(arb[crt][i], nivel+1);
depth.push_back(nivel);
euler.push_back(crt);
}
}
void prepareRMQ()
{
k = depth.size()-1;
for (int i = 1; i <= k; i++)
rm[0][i] = i;
for (int i = 1; 1<<i <= k; i++)
for (int j = 1; j + (1<<(i-1)) <= k; j++)
{
int aux = j + (1<<(i-1));
if (depth[rm[i-1][j]] < depth[rm[i-1][aux]])
rm[i][j] = rm[i-1][j];
else
rm[i][j] = rm[i-1][aux];
}
}
void prepareLog()
{
int crt = 1, pwr = 0;
for (int i = 1; i <= 2*n+10; i++)
{
if (i >= crt<<1) crt *= 2, pwr++;
log[i] = pwr;
}
}
void debug()
{
for (int i = 1; i < euler.size(); i++)
printf("%d ", depth[i]);
printf("\n");
for (int i = 1; 1<<i <= k; i++, printf("\n"))
for (int j = 1; j + (1<<(i-1)) <= k; j++)
printf("%d ", depth[rm[i][j]]);
}
int minAncest(int x, int y)
{
if (x > y) swap(x, y);
int len = y-x+1, lg = log[len];
if (depth[rm[lg][x]] < depth[rm[lg][y+1-(1<<lg)]])
return rm[lg][x];
return rm[lg][y+1-(1<<lg)];
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
citire();
prepareEuler(1, 0); /// Eulerian tree traversal
prepareRMQ(); /// Prepare rmq matrix
prepareLog();
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d %d", &x, &y);
printf("%d\n", euler[minAncest(viz[x], viz[y])]);
}
return 0;
}