Pagini recente » Cod sursa (job #1396385) | Cod sursa (job #1488381) | Cod sursa (job #782287) | Cod sursa (job #931276) | Cod sursa (job #1634039)
#include<stdio.h>
using namespace std;
const int N = 100005, P = 18;
int lst[N], vf[N], urm[N], nrm;
bool viz[N];
int poz[N], put[2 * N], log[2 * N];
struct euler
{
int ap, depth;
};
int ct = 0;
euler v[2 * N], mat[P][2 * N];
void adauga (int x, int y)
{
vf[++nrm] = y;
urm[nrm] = lst[x];
lst[x] = nrm;
}
void dfs (int depth, int x)
{
int y, p;
p = lst[x];
if (viz[x] == false)
poz[x] = ct + 1;
viz[x] = true;
v[++ct].ap = x;
v[ct].depth = depth;
while (p != 0)
{
y = vf[p];
if (viz[y] == false)
{
dfs (depth + 1, y);
v[++ct].ap = x;
v[ct].depth = depth;
}
p = urm[p];
}
}
int precalculare ()
{
int i, p = 1, c = 0;
for (i = 1; i <= ct; i++)
{
if ((p << 1) <= i)
{
p <<= 1;
++c;
}
put[i] = p;
log[i] = c;
}
p = 1;
c = 0;
while (p <= ct)
{
p <<= 1;
c++;
}
for (i = 1; i <= ct; i++)
mat[0][i] = v[i];
return c - 1;
}
euler minim (euler a, euler b)
{
if (a.depth < b.depth)
return a;
return b;
}
int main ()
{
FILE *in, *out;
in = fopen ("lca.in", "r");
out = fopen ("lca.out", "w");
int n, m;
fscanf (in, "%d%d", &n, &m);
int i, x;
for (i = 2; i <= n; i++)
{
fscanf (in, "%d", &x);
adauga (x, i);
adauga (i, x);
}
dfs (0, 1);
int j, p = precalculare(), k = 1;
for (i = 1; i <= p; i++)
{
for (j = 1; j <= ct; j++)
if (j + k <= ct)
mat[i][j] = minim (mat[i - 1][j], mat[i - 1][j + k]);
k <<= 1;
}
int y, aux, putere;
for (i = 1; i <= m; i++)
{
fscanf (in, "%d%d", &x, &y);
if (poz[x] > poz[y])
{
aux = x;
x = y;
y = aux;
}
x = poz[x];
y = poz[y];
putere = put[y - x + 1];
p = log[y - x + 1];
fprintf (out, "%d\n", minim (mat[p][x], mat[p][y - putere + 1]).ap);
}
return 0;
}