Pagini recente » Cod sursa (job #2474499) | Cod sursa (job #739443) | Cod sursa (job #1275319) | Cod sursa (job #1043003) | Cod sursa (job #2713735)
#include <bits/stdc++.h>
#define lim 100005
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, path[2*lim], pos[lim], k=0, mat[20][lim*2];
int ran[2*lim];
vector <int> v[lim];
void read()
{
int x;
in>>n>>m;
for(int i=2; i<=n; ++i)
{
in>>x;
v[x].push_back(i);
}
}
void dfs(int x,int r)
{
path[++k]=x;
ran[k]=r;
pos[x]=k;
for(int i=0; i<v[x].size(); ++i)
{
dfs(v[x][i], r+1);
path[++k]=x;
ran[k]=r;
pos[x]=k;
}
}
int find_pow(int x)
{
int pw=1;
for(int i=0; i<=20; ++i)
{
if(pw>x)
{
return i-1;
}
mat[i][0]=pw;
pw=pw*2;
}
}
void create_sparse_table()
{
int l=2*n-1;
int pw=find_pow(l);
for(int i=0; i<=pw; ++i)
{
for(int j=1; j+mat[i][0]-1<=l; ++j)
{
if(i==0)
{
mat[i][j]=path[j];
}
else if(i>0)
{
mat[i][j]=min(mat[i-1][j],mat[i-1][j+mat[i-1][0]]);
}
//cout<<mat[i][j]<<" ";
}
//cout<<'\n';
}
}
void solve()
{
int x, y;
for(int i=1; i<=m; ++i)
{
in>>x>>y;
if(pos[x]>pos[y])
{
swap(x,y);
}
int lin=find_pow(pos[y]-pos[x]+1);
out<<min(mat[lin][pos[x]], mat[lin][pos[y]-mat[lin][0]])<<'\n';
}
}
int main()
{
read();
dfs(1, 1);
/*for(int i=1; i<=2*n; ++i)
{
cout<<path[i]<<" "<<ran[i]<<" "<<pos[i]<<'\n';
}
cout<<'\n';*/
create_sparse_table();
solve();
return 0;
}