Pagini recente » Cod sursa (job #1289671) | Cod sursa (job #63331) | Cod sursa (job #1944977) | Cod sursa (job #2572664) | Cod sursa (job #2205535)
#include <bits/stdc++.h>
#define nmax 100010
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
vector <int> v[2*nmax];
int n, m, k;
int logaritm[2*nmax], euler[2*nmax], nivel[2*nmax], prima[2*nmax];
int dp[4*nmax][20]; // dp[i][j], minimul dintre pozitia j si j+2^(i-1);
void dfs( int nod, int unde )
{
euler[++k] = nod;
nivel[k] = unde;
prima[nod] = k;
for ( auto x:v[nod] )
{
dfs(x, unde+1);
euler[++k] = nod;
nivel[k] = unde;
}
}
void rmq()
{
for ( int i = 2; i <= k; ++i )
logaritm[i] = logaritm[i/2]+1;
for ( int i = 1; i <= k; ++i )
dp[i][0] = i;
for ( int i = 1; i <= logaritm[k]; ++i )
{
for ( int j = 1; j <= k; ++j )
{
if ( j+(1<<(i-1)) > k )
break;
if ( nivel[dp[j][i-1]] > nivel[dp[j+(1<<(i-1))][i-1]] )
dp[j][i] = dp[j+(1<<(i-1))][i-1];
else
dp[j][i] = dp[j][i-1];
}
}
}
int lca(int x, int y)
{
if ( nivel[dp[x][logaritm[y-x]]] > nivel[dp[y-(1<<logaritm[y-x])][logaritm[y-x]]] )
return euler[dp[y-(1<<logaritm[y-x])][logaritm[y-x]]];
return euler[dp[x][logaritm[y-x]]];
}
int main()
{
ios::sync_with_stdio(false);
fin.tie(0); fout.tie(0);
fin>>n>>m;
for ( int i = 2; i <= n; ++i )
{
int tata;
fin>>tata;
v[tata].push_back(i);
}
dfs(1, 0);
rmq();
while ( m-- )
{
int x, y, a, b;
fin>>a>>b;
x = prima[a];
y = prima[b];
if ( x > y )
swap (x, y);
fout<<lca(x, y)<<'\n';
}
}