Pagini recente » Cod sursa (job #1884761) | Cod sursa (job #1586481) | Cod sursa (job #2714869) | Cod sursa (job #518817) | Cod sursa (job #2220207)
#include <bits/stdc++.h>
#define nmax 100010
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
int n, m, limit;
int first_Euler[4*nmax], logarithm[4*nmax], euler[4*nmax], level[4*nmax];
int dp[4*nmax][30];
vector <int> tree[nmax];
void eulerRepresentation(int node, int current_Level)
{
euler[++limit] = node;
level[limit] = current_Level;
first_Euler[node] = limit;
for ( auto x:tree[node] )
{
eulerRepresentation(x, current_Level+1);
euler[++limit] = node;
level[limit] = current_Level;
}
}
void rangeMinimumQueryPrecalc()
{
for ( int i = 2; i <= limit; ++i )
logarithm[i] = logarithm[i/2]+1;
for ( int i = 1; i <= limit; ++i )
dp[i][0] = i;
for ( int i = 1; i <= logarithm[limit]; ++i )
{
for ( int j = 1; j <= limit; ++j )
{
if ( j+(1<<i) > limit )
break;
if ( level[dp[j][i-1]] > level[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 answerQuery(int first_Value, int second_Value)
{
int range = second_Value-first_Value+1;
if ( level[dp[first_Value][logarithm[range]]] > level[dp[second_Value-(1<<logarithm[range])+1][logarithm[range]]] )
return euler[dp[second_Value-(1<<logarithm[range])+1][logarithm[range]]];
else
return euler[dp[first_Value][logarithm[range]]];
}
int main()
{
fin>>n>>m;
for ( int i = 2; i <= n; ++i )
{
int father;
fin>>father;
tree[father].push_back(i);
}
eulerRepresentation(1, 0);
rangeMinimumQueryPrecalc();
for ( int i = 1; i <= m; ++i )
{
int a, b, first_Value, second_Value;
fin>>a>>b;
first_Value = first_Euler[a];
second_Value = first_Euler[b];
if ( first_Value > second_Value )
swap(first_Value, second_Value);
fout<<answerQuery(first_Value, second_Value)<<'\n';
}
}