Cod sursa(job #509308)
#include <fstream>
#include <vector>
using namespace std;
inline int min( int a, int b ) {
return a<b?(a):(b);
}
const int N = 100005;
int nr,v[N], n, m, h[2* ( N +1 )], eul[2 * (N + 1)], l[2*N], p, poz[N], pz[20][N * 2], P[20] ;
vector<int> a[N];
int dfs( int k ) {
int i;
eul[ ++nr ] = k;
poz[k] = nr;
for( i = 0; i < a[k].size(); ++i)
if( !v[a[k][i]] )
v[a[k][i]] = v[k] + 1,dfs(a[k][i]),
eul[ ++nr] = k, poz[k] = nr;
}
inline void precalc() {
int i, j;
for(i = 1; i <= nr; ++i)
h[i] = v[eul[i]];
p = 1;
j = -1;
for(i = 1; i <= nr; ++i) {
if ( i == p )
++j,p*=2;
if( i <= p )
l[i] = j;
}
p = 1;
for( i = 1; i <= nr; ++i)
pz[0][i]= i;
for(i = 1; i <= l[nr]; ++i, p*=2)
for(j = 1; j<= nr; ++j)
if(j + p*2 <= nr +1) {
pz[i][j] = pz[i - 1][j];
if( h[pz[i][j]] >h[pz[i - 1][j + p]] )
pz[i][j] = pz[i - 1][j + p];
}
}
inline int RMQ(int i, int j) {
int w = l[j - i +1];
if( h[pz[w][i]]< h[pz[w][j - (1<<w) + 1]] )
return pz[w][i];
else
return pz[w][j - (1<<w) + 1 ];
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
int j,i, x, y;
fin>>n>>m;
for( i = 2; i <= n; ++i)
fin>>y, a[i].push_back(y), a[y].push_back(i);
v[1] = 1;
dfs(1);
precalc();
for( i = 1; i <=m ;++i) {
fin>>x>>y;
if(poz[x]>poz[y]) {
j = x;
x = y;
y = j;
}
fout<<eul[RMQ(poz[x],poz[y])]<<'\n';
}
fin.close();
fout.close();
return 0;
}