Pagini recente » Cod sursa (job #616670) | Cod sursa (job #852938) | Cod sursa (job #147964) | Cod sursa (job #1441144) | Cod sursa (job #1666355)
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N_max = 100005;
const int Log = 18;
int lst[N_max];
int vf[N_max];
int urm[N_max];
int nr;
int L[N_max];
bool viz[N_max];
int E[2 * N_max - 1], level[2 * N_max - 1];
int K;
int First[N_max];
int rmq[2 * N_max - 1][Log];
int lg[2 * N_max - 1];
int N, Q;
void adauga(int x, int y)
{
// ADAUGA IN LISTA LUI x PE y
nr++;
vf[nr] = y;
urm[nr] = lst[x];
lst[x] = nr;
}
void read()
{
int i, x;
in >> N >> Q;
for(i = 2; i <= N; i++)
{
in >> x;
adauga(x, i);
}
}
void euler(int x)
{
int p, y;
viz[x] = true;
E[++K] = x;
if(!First[x]) First[x] = K;
// PARCURG VECINII y AI LUI x
p = lst[x];
while(p != 0)
{
y = vf[p];
if(!viz[y])
{
L[y] = 1 + L[x];
euler(y);
E[++K] = x;
}
p = urm[p];
}
}
void RMQ()
{
int i, j;
for(i = 1; i <= K; i++) level[i] = L[ E[i] ];
lg[1] = 0;
for(i = 2; i <= K; i++) lg[i] = lg[i/2] + 1;
for(i = 1; i <= K; i++) rmq[i][0] = i;
for(i = 1; i <= K; i++)
for(j = 1; (1 << j) <= i; j++)
{
int k = i - (1 << (j - 1));
rmq[i][j] = rmq[i][j - 1];
if(level[ rmq[k][j - 1] ] < level[ rmq[i][j] ])
rmq[i][j] = rmq[k][j - 1];
}
}
void query()
{
int a, b;
for(int q = 1; q <= Q; q++)
{
in >> a >> b;
a = First[a];
b = First[b];
if(a > b) swap(a, b);
int l = lg[b - a + 1];
int ans = rmq[b][l];
if(level[rmq[a + (1 << l) - 1][l]] < level[ans])
ans = rmq[a + (1 << l) - 1][l];
out << E[ans] << '\n';
}
}
int main()
{
read();
euler(1);
RMQ();
query();
return 0;
}