Pagini recente » Cod sursa (job #3138297) | Cod sursa (job #433231) | Cod sursa (job #1612336) | Rating Stefan Robert (Robert_Horia) | Cod sursa (job #3000173)
#include<fstream>
#include<vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int NMAX = 1e5 + 10;
const int MAXLOG = 20;
int dp[MAXLOG][2 * NMAX],euler[2 * NMAX],nivel[NMAX],poz[NMAX],loga[2 * NMAX],e;
vector<int> vecini[NMAX];
void dfs(int nod)
{
euler[++e] = nod;
poz[nod] = e;
for(auto it : vecini[nod])
{
if(poz[it]) continue;
dfs(it);
nivel[nod] = max(nivel[nod],nivel[it] + 1);
euler[++e] = nod;
}
}
int lca(int a,int b)
{
int pa = poz[a],pb = poz[b];
if(pa > pb) swap(pa,pb);
int p = loga[pb - pa + 1];
int ans = dp[p][pa];
int other = pb - (1 << p) + 1;
if(nivel[dp[p][other]] < nivel[ans]) ans = dp[p][other];
return ans;
}
int main()
{
int n,q,a,b; cin >> n >> q;
for(int i = 2; i <= n ; i++)
{
cin >> a;
vecini[a].emplace_back(i);
}
dfs(1); dp[0][1] = euler[1];
for(int i = 2; i <= e ; i++)
{
dp[0][i] = euler[i];
loga[i] = loga[i / 2] + 1;
}
for(int l = 1; l <= loga[e] ; l++)
{
for(int i = 1; i + (1 << l) - 1 <= e ; i++)
{
dp[l][i] = dp[l - 1][i]; int other = i + (1 << (l - 1));
if(nivel[dp[l - 1][other]] > nivel[dp[l][i]])
dp[l][i] = dp[l - 1][other];
}
}
while(q--)
{
cin >> a >> b;
cout << lca(a,b) << '\n';
}
}