Pagini recente » Cod sursa (job #2802673) | Cod sursa (job #251450) | Cod sursa (job #2806862) | Cod sursa (job #2802696) | Cod sursa (job #3215677)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, Q;
int P[200005], e[200005], expo[200005], nivel[200005], rmq[20][200005];
vector<int> L[100005];
void Euler(int k, int level)
{
e[++m] = k;
P[k] = m;
nivel[m] = level;
for (int i : L[k])
{
Euler(i, level + 1);
e[++m] = k;
nivel[m] = level;
}
}
void MakeRMQ()
{
int i, j, L, A, B;
expo[1] = 0;
for (i = 2; i <= m; i++)
expo[i] = expo[i / 2] + 1;
for (i = 1; i <= m; i++)
rmq[0][i] = i;
for (i = 1; i <= expo[m]; i++)
{
L = (1 << i);
for (j = 1; j <= m - L + 1; j++)
{
A = rmq[i - 1][j];
B = rmq[i - 1][j + L / 2];
if (nivel[A] <= nivel[B])
rmq[i][j] = A;
else
rmq[i][j] = B;
}
}
}
int LCA(int A, int B)
{
int L, E;
A = P[A];
B = P[B];
if (A > B)
swap(A, B);
E = expo[B - A + 1];
L = (1 << E);
A = rmq[E][A];
B = rmq[E][B - L + 1];
if (nivel[A] <= nivel[B])
return e[A];
return e[B];
}
int main()
{
int i, j;
fin >> n >> Q;
for (i = 2; i <= n; i++)
{
fin >> j;
L[j].push_back(i);
}
Euler(1, 1);
MakeRMQ();
while (Q--)
{
fin >> i >> j;
fout << LCA(i, j) << "\n";
}
return 0;
}