Pagini recente » Cod sursa (job #2459162) | Cod sursa (job #586748) | Cod sursa (job #2090458) | Cod sursa (job #1375887) | Cod sursa (job #2504487)
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <cstring>
using namespace std;
//#include <iostream>
#include <fstream>
//ifstream cin ("input.in");
//ofstream cout ("output.out");
ifstream cin ("lca.in");
ofstream cout ("lca.out");
struct node {
int euler, level;
};
static const int NMAX = 1e5+5;
static const int MMAX = 2e6+5;
int logar[MMAX];
int firstEuler[MMAX];
node v[MMAX];
int dp[MMAX][25];
vector <int> graph[NMAX];
int k;
void dfs(int vertex, int depth) {
v[++k] = {vertex, depth};
firstEuler[vertex] = k;
for ( auto x:graph[vertex] ) {
dfs(x, depth+1);
v[++k] = {vertex, depth};
}
}
void genRMQ () {
int K = logar[k];
for ( int i = 1; i <= k; ++i ) {
dp[i][0] = (v[i].level <= v[i+1].level ? i : i+1 );
// dp[i][0] = i;
}
for ( int i = 1; i <= K; ++i ) {
for ( int j = 1; j <= k; ++j ) {
if ( j+(1<<i) > k ) {
break;
}
if ( v[dp[j][i-1]].level <= v[dp[j+(1<<(i-1))][i-1]].level ) {
dp[j][i] = dp[j][i-1];
}
else {
dp[j][i] = dp[j+(1<<(i-1))][i-1];
}
}
}
}
int getRMQ (int l, int r) {
if ( l > r ) {
swap(l, r);
}
int dist = r-l+1;
if ( v[dp[l][logar[dist]]].level <= v[dp[r-(1<<logar[dist])+1][logar[dist]]].level ) {
return v[dp[l][logar[dist]]].euler;
}
return v[dp[r-(1<<logar[dist])+1][logar[dist]]].euler;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
for ( int i = 2; i <= MMAX-5; ++i ) {
logar[i] = logar[i/2]+1;
}
int n, m;
cin>>n>>m;
for ( int i = 2; i <= n; ++i ) {
int x;
cin>>x;
graph[x].push_back(i);
}
dfs(1, 0);
genRMQ();
for ( int i = 1; i <= m; ++i ) {
int a, b;
cin>>a>>b;
cout<<getRMQ(firstEuler[a], firstEuler[b])<<'\n';
}
}