Pagini recente » Cod sursa (job #2809309) | Cod sursa (job #3356744) | Cod sursa (job #3344573) | Cod sursa (job #871121) | Cod sursa (job #3345110)
#include <fstream>
#include <vector>
#define NMAX 100005
#define LOG 18
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int N,M,poz,tata[NMAX],nivel[NMAX];
int first[NMAX],euler[2*NMAX],rmq[2*NMAX][LOG];
vector<int> tree[NMAX];
void citire()
{
fin>>N>>M;
for(int i=2; i<=N; i++)
{
fin>>tata[i];
tree[tata[i]].push_back(i);
}
}
void DFS(int nod)
{
euler[++poz]=nod;
first[nod]=poz;
for(int i=0; i<tree[nod].size(); i++)
{
int next_nod=tree[nod][i];
nivel[next_nod]=nivel[nod]+1;
DFS(next_nod);
euler[++poz]=nod;
}
}
int lca(int a, int b)
{
int st,dr;
st=first[a];
dr=first[b];
if(st>dr)
{
swap(st,dr);
}
int l=dr-st+1;
int k=31-__builtin_clz(l);
int x=rmq[st][k];
int y=rmq[dr-(1<<k)+1][k];
if(nivel[euler[x]]<nivel[euler[y]])
{
return euler[x];
}
else
{
return euler[y];
}
}
int main()
{
citire();
poz=0;
DFS(1);
for(int i=1; i<=poz; i++)
{
rmq[i][0]=i;
}
for(int j=1; (1<<j)<=poz; j++)
{
for(int i=1; i+(1<<j)-1<=poz; i++)
{
int a=rmq[i][j-1];
int b=rmq[i+(1<<(j-1))][j-1];
if(nivel[euler[a]]<nivel[euler[b]])
{
rmq[i][j]=a;
}
else
{
rmq[i][j]=b;
}
}
}
int a,b;
for(int q=1; q<=M; q++)
{
fin>>a>>b;
fout<< lca(a,b) << "\n";
}
return 0;
}