Pagini recente » Cod sursa (job #1009939) | Cod sursa (job #111085) | Cod sursa (job #2030868) | Istoria paginii runda/concurs_2014/clasament | Cod sursa (job #3204128)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int N , Q , K , niv[210000] , euler[210000] , dp[21][210000] , poz[100001];
vector <int> adList[100001];
int p[210000];
void DFS (int V , int P)
{
niv[V] = niv[P] + 1;
euler[++K] = V;
poz[V] = K;
for (int U : adList[V])
{
if(U != P)
DFS(U , V);
euler[++K] = U;
}
}
void Calc ()
{
p[1] = 0;
for(int i = 2; i <= K; ++i)
p[i] = 1 + p[i / 2];
for(int i = 1; i <= K; ++i)
dp[0][i] = euler[i];
for(int i = 1; (1 << i) <= K; ++i)
for(int j = 1; j <= K; ++j)
{
dp[i][j] = dp[i - 1][j];
int p = (1 << (i - 1));
if(niv[dp[i - 1][j - p]] < niv[dp[i - 1][j]])
dp[i][j] = dp[i - 1][j - p];
}
}
int LCA (int A , int B)
{
int st = poz[A] , dr = poz[B];
if(st > dr)
swap(st , dr);
int l = p[dr - st + 1];
int p = (1 << l);
A = dp[l][st + p - 1];
B = dp[l][dr];
if(niv[A] < niv[B])
return A;
return B;
}
int main()
{
fin >> N >> Q;
for(int i = 2; i <= N; ++i)
{
int X;
fin >> X;
adList[i].push_back(X);
adList[X].push_back(i);
}
DFS (1 , 0);
Calc();
while (Q --)
{
int A , B;
fin >> A >> B;
fout << LCA(A , B) << "\n";
}
}