Pagini recente » Cod sursa (job #1626759) | Cod sursa (job #2480633) | Cod sursa (job #780860) | Cod sursa (job #1462205) | Cod sursa (job #643719)
Cod sursa(job #643719)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int MAXN = 100005 , INF = int(2e9);
vector<int> G[MAXN];
int N , M , H[MAXN<<1] , L[MAXN<<1] , First[MAXN<<1] , K , sol , hsol;
int Arb[MAXN<<4] , start , finish;
void dfs(int node,int lev)
{
H[++K] = node; L[K] = lev; First[node] = K;
for(vector<int>::const_iterator w = G[node].begin();w!=G[node].end();++w)
{
dfs(*w,lev + 1);
H[++K] = node; L[K] = lev;
}
}
void build(int root,int left,int right)
{
if(left == right)
{
Arb[root] = left;
return;
}
int lson = 2*root , rson = 2*root + 1 , mij = (left + right)>>1;
build(lson,left,mij);
build(rson,mij + 1,right);
if(L[Arb[lson]] <= L[Arb[rson]])
Arb[root] = Arb[lson];
else
Arb[root] = Arb[rson];
}
void query(int root,int left,int right)
{
if(start<=left && right<=finish)
{
if( hsol > L[Arb[root]])
sol = H[Arb[root]] , hsol = L[Arb[root]];
return;
}
int lson = 2*root , rson = 2*root + 1 , mij = (left + right)>>1;
if(start <= mij) query(lson,left,mij);
if(mij < finish) query(rson,mij + 1,right);
}
int lca(int x,int y)
{
start = First[x] , finish = First[y];
if(start > finish) swap(start,finish);
sol = hsol = INF;
query(1,1,K);
return sol;
}
int main()
{
fin>>N>>M;
for(int i = 2;i<=N;++i)
{
int x ;
fin>>x;
G[x].push_back(i);
}
dfs(1,0);
build(1,1,K);
for(;M;M--)
{
int x , y;
fin>>x>>y;
fout<<lca(x,y)<<'\n';
}
return 0;
}