Pagini recente » Diferente pentru sandbox intre reviziile 572 si 573 | Cod sursa (job #1588513) | Borderou de evaluare (job #1299354) | Cod sursa (job #2361131) | Cod sursa (job #1519516)
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxN 100002
#define maxL 20
using namespace std;
int n, m, nr, ne;
int e[maxN * 2], lev[maxN * 2], urm[2 * maxN], vf[maxN * 2], lst[maxN], t[maxN], pos[maxN], d[maxL][maxN * 2], Log[maxN * 2];
void add(int x, int y)
{
++ nr;
vf[nr] = y;
urm[nr] = lst[x];
lst[x] = nr;
}
void read()
{
int i, x;
freopen("lca.in", "r", stdin);
scanf("%d %d", &n, &m);
for (i = 2; i <= n; ++ i)
{
scanf("%d", &x);
add(x, i);
t[i] = x;
}
}
void euler(int x)
{
e[++ ne] = x;
if (pos[x] == 0)
pos[x] = ne;
lev[x] = lev[t[x]] + 1;
int p = lst[x], y;
while (p != 0)
{
y = vf[p];
euler(y);
e[++ ne] = x;
p = urm[p];
}
}
void solve()
{
int i, j;
for (i = 1; i <= ne; ++ i)
d[0][i] = e[i];
for (i = 2; i <= ne; ++ i)
Log[i] = Log[i / 2] + 1;
for (i = 1; i <= Log[ne]; ++ i)
for (j = 1; j <= ne; ++ j)
{
d[i][j] = d[i - 1][j - (1 << (i - 1))];
if (lev[d[i][j]] > lev[d[i - 1][j]])
d[i][j] = d[i - 1][j];
}
}
void write()
{
int z, t, x, y, k;
freopen("lca.out", "w", stdout);
while (m --)
{
scanf("%d %d", &x, &y);
z = pos[x];
t = pos[y];
if (z > t)
swap(z, t);
k = Log[t - z];
if (lev[d[k][t]] < lev[d[k][z + (1 << k)]-1])
printf("%d\n", d[k][t]);
else
printf("%d\n", d[k][z + (1 << k)-1]);
}
}
int main()
{
read();
euler(1);
solve();
write();
return 0;
}