Pagini recente » Cod sursa (job #1956292) | Cod sursa (job #318055) | Cod sursa (job #940676) | Cod sursa (job #2889549) | Cod sursa (job #433395)
Cod sursa(job #433395)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
#define NMAX 100004
#define KMAX 230000
#define LOGK 20
int M[LOGK][KMAX], E[KMAX],Niv[KMAX],Ap[NMAX],n,m,k=0;
vector <int> A[NMAX];
ifstream fin("lca.in");
ofstream fout("lca.out");
void cit()
{
fin>>n>>m;
int i,tata;
for (i=2;i<=n;++i)
{
fin>>tata;
A[tata].push_back(i);
}
}
void euler(int x, int niv)
{
E[++k]=x;
Niv[k]=niv;
Ap[x]=k; //prima aparitie
size_t i;
for (i=0;i<A[x].size();++i)
{
euler(A[x][i],niv+1);
E[++k]=x;
Niv[k]=niv;
Ap[x]=k;
}
}
void RMQ()
{
int i,j;
for (i=1;i<=k;++i)
M[0][i]=i;
for (j=1; (1<<j)<=k;++j)
for (i=1;i+(1<<j)-1<=k;++i)
if (Niv[M[j-1][i]]<Niv[M[j-1][i+(1<<(j-1))]])
M[j][i]=M[j-1][i];
else M[j][i]=M[j-1][i+(1<<(j-1))];
}
int LCA(int x, int y)
{
if (Ap[x]>Ap[y]) swap(x,y);
x=Ap[x]; y=Ap[y];
int dif=y-x+1, j;
for (j=0; (1<<j)<=dif; ++j);
--j;
if (Niv[M[j][x]]<Niv[M[j][y-(1<<j)+1]]) return E[M[j][x]];
return E[M[j][y-(1<<j)+1]];
}
int main()
{
cit();
euler(1,0);
RMQ();
for (;m;m--)
{ int x,y;
fin>>x>>y;
fout<<LCA(x,y)<<"\n";
}
return 0;
}