Pagini recente » Cod sursa (job #1632811) | Cod sursa (job #768104) | Cod sursa (job #507004) | Cod sursa (job #2061822) | Cod sursa (job #1414089)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<cmath>
#include<climits>
using namespace std ;
#define maxn 100005
int N, M ;
vector<int> graf[maxn] ;
int euler[2 * maxn], nivel[2 * maxn], apare[maxn], nr ;
bool sel[maxn] ;
int m[2 * maxn][30], lg[2 * maxn] ;
void dfs(int nod, int level)
{
sel[nod] = true ;
euler[++nr] = nod ;
nivel[nr] = level ;
apare[nod] = nr ;
for(size_t i = 0; i < graf[nod].size(); ++i)
{
int vecin = graf[nod][i] ;
if( sel[vecin] == false )
{
dfs(vecin, level + 1) ;
euler[++nr] = nod ;
nivel[nr] = level ;
}
}
}
void precalc_logaritm()
{
lg[1] = 0 ;
for(int i = 2; i <= nr; ++i)
lg[i] = lg[i / 2] + 1 ;
}
void rmq()
{
for(int i = 1; i <= nr; ++i)
m[i][0] = i ;
int pas = 1 ;
for(int j = 0; pas <= nr; ++j)
{
for(int i = 1; i <= nr; ++i)
{
if( i + pas > nr )
m[i][j + 1] = m[i][j] ;
else
{
if( nivel[ m[i][j] ] < nivel[ m[i + pas][j] ] )
m[i][j + 1] = m[i][j] ;
else
m[i][j + 1] = m[i + pas][j] ;
}
}
pas *= 2 ;
}
}
int lca(int x, int y)
{
if( x > y )
swap(x, y) ;
int dif = y - x + 1 ;
int pas = ( 1 << lg[dif] ) ;
if( nivel[ m[x][ lg[dif] ] ] < nivel[ m[y - pas + 1][ lg[dif] ] ] )
return euler[ m[x][ lg[dif] ] ] ;
return euler[ m[y - pas + 1][ lg[dif] ] ] ;
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &N, &M);
for(int i = 1; i < N; ++i)
{
int x ;
scanf("%d", &x);
graf[x].push_back(i + 1) ;
graf[i + 1].push_back(x) ;
}
dfs( 1, 0 ) ;
precalc_logaritm() ;
rmq() ;
for(int i = 1; i <= M; ++i)
{
int x, y ;
scanf("%d%d", &x, &y);
printf("%d\n", lca( apare[x], apare[y] ) );
}
return 0 ;
}