Pagini recente » Cod sursa (job #717596) | Cod sursa (job #2833092) | Cod sursa (job #2021412) | Cod sursa (job #615637) | Cod sursa (job #3286648)
#include <bits/stdc++.h>
using namespace std;
//aproapeperm
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, Q;
int rmq[20][200005], euler[200005], top, e[200005], nivel[200005], P[200005];
vector<int> L[100005];
void Euler(int k, int level)
{
euler[++top] = k;
P[k] = top;
nivel[top] = level;
for (int i : L[k])
{
Euler(i, level + 1);
euler[++top] = k;
nivel[top] = level;
}
}
void BuildRMQ()
{
int i, j, L, A, B;
e[1] = 0;
for (i = 2; i <= top; i++)
e[i] = e[i / 2] + 1;
for (i = 1; i <= top; i++)
rmq[0][i] = i;
for (i = 1; i <= e[top]; i++)
{
L = (1 << (i - 1));
for (j = 1; j <= top - 2 * L + 1; j++)
{
A = rmq[i - 1][j]; B = rmq[i - 1][j + L];
if (nivel[A] <= nivel[B]) rmq[i][j] = A;
else rmq[i][j] = B;
}
}
}
int LCA(int A, int B)
{
int L, expo;
A = P[A]; B = P[B];
if (A > B) swap(A, B);
expo = e[B - A + 1];
L = (1 << expo);
A = rmq[expo][A]; B = rmq[expo][B - L + 1];
if (nivel[A] <= nivel[B]) return euler[A];
return euler[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);
BuildRMQ();
while (Q--)
{
fin >> i >> j;
fout << LCA(i, j) << "\n";
}
return 0;
}