Pagini recente » Cod sursa (job #2211947) | Cod sursa (job #558848) | Cod sursa (job #3001469) | Cod sursa (job #267350) | Cod sursa (job #2749418)
#include <bits/stdc++.h>
using namespace std;
const int mxn = 100 * 1000 + 10;
int n, m;
int lvl[ mxn ];
int arb[ 8 * mxn ];
vector< int > g[ mxn ];
vector< int > euler;
int indexx[ mxn ];
void dfs(int x, int level){
euler.push_back( x );
lvl[ x ] = level;
indexx[ x ] = euler.size() - 1;
for(auto it: g[ x ]){
if(lvl[ it ] == 0){
dfs( it, level + 1);
euler.push_back( x );
}
}
}
void build(int st, int sf, int nod){
if(st == sf){
arb[ nod ] = st;
return;
}
int mid = (st + sf) / 2;
build(st, mid, 2 * nod + 1);
build(mid + 1, sf, 2 * nod + 2);
if(lvl[ euler[ arb[ 2 * nod + 1] ] ] < lvl[ euler[ arb[ 2 * nod + 2] ] ]){
arb[ nod ] = arb[ 2 * nod + 1 ];
}
else{
arb[ nod ] = arb[ 2 * nod + 2];
}
}
int query(int st, int sf, int nod, int x, int y){
if(x > sf || y < st){
return indexx[ 0 ];
}
if(x <= st && y >= sf){
return arb[ nod ];
}
int mid = (st + sf) / 2;
int v1 = query(st, mid, 2 * nod + 1, x, y);
int v2 = query(mid + 1, sf, 2 * nod + 2, x, y);
if(lvl[ euler[ v1 ]] < lvl[ euler[ v2 ]]){
return v1;
}
else{
return v2;
}
}
int lca(int x, int y){
if(indexx[ x ] > indexx[ y ]){
swap(x, y);
}
return euler[ query(0, euler.size() - 2, 0, indexx[ x ], indexx[ y ]) ];
}
int main()
{
ifstream cin("lca.in");
ofstream cout("lca.out");
cin>> n >> m;
for(int i = 2, x; i <= n; i++){
cin>> x;
g[ i ].push_back( x );
g[ x ].push_back( i );
}
dfs(1, 1);
build(0, euler.size() - 1, 0);
euler.push_back( 0 );
indexx[ 0 ] = euler.size() - 1;
lvl[ 0 ] = INT_MAX;
for(int i = 0, x, y; i < m; i++){
cin>> x >> y;
cout<< lca(x, y) << '\n';
}
return 0;
}