Pagini recente » Cod sursa (job #2927367) | Cod sursa (job #205782) | Cod sursa (job #476933) | Cod sursa (job #885757) | Cod sursa (job #1059094)
#include <cstdio>
#include <vector>
#define nmax 100000+5
#define range(i, a, b) int i = (a); i <= (b); i++
#define every(it, C) vector<int>::iterator it = C.begin(); it != C.end(); it++
using namespace std;
vector<int> graf[nmax];
vector<int> euler;
int n;
int R[20][nmax];
int pozitieEuler[nmax];
int inaltime[nmax];
void parcurgereEuler(int nod, int h)
{
euler.push_back(nod);
pozitieEuler[nod] = euler.size();
inaltime[nod] = h;
if (!graf[nod].empty())
for (every(fiu, graf[nod]))
{
parcurgereEuler(*fiu, h+1);
euler.push_back(nod);
}
}
void formareMatriceRMQ()
{
int i, j;
int l = euler.size();
int x, y;
for (j = 0; j < l; j++)
R[0][j+1] = euler[j];
for (i = 1; (1 << i) <= l; i++)
for (j = 1; j + (1 << i) -1 <= l; j++)
{
x = R[i-1][j];
y = R[i-1][j+(1<<(i-1))];
if (inaltime[x] < inaltime[y])
R[i][j] = x;
else
R[i][j] = y;
}
}
int interogareRMQ(int x, int y)
{
int a, b;
int log = 0;
while (1 << (log+1) <= y-x)
log++;
a = R[log][x];
b = R[log][y-(1<<log)+1];
if (inaltime[a] < inaltime[b])
return a;
else
return b;
}
void debugRMQ()
{
int i, j;
int l = euler.size();
for (i = 0; (1 << i) <= l; i++)
{
for (j = 0; j + (1 << i) -1 < l; j++)
printf("%d\t", R[i][j]);
printf("\n");
}
for (i = 1; i <= n; i++)
printf("inaltime[%d] = %d\n", i, inaltime[i]);
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int m, x, y;
scanf("%d%d", &n, &m);
for (range(i, 2, n))
{
scanf("%d", &x);
graf[x].push_back(i);
}
parcurgereEuler(1, 1);
formareMatriceRMQ();
//debugRMQ();
for (range(i, 1, m))
{
scanf("%d%d", &x, &y);
printf("%d\n", interogareRMQ(pozitieEuler[x], pozitieEuler[y] ));
}
return 0;
}