Pagini recente » Cod sursa (job #1174710) | Cod sursa (job #2338974) | Cod sursa (job #884292) | Cod sursa (job #2600069) | Cod sursa (job #737666)
Cod sursa(job #737666)
#include <fstream>
#include <stdlib.h>
#include <cmath>
#define NMax 100001
#define max(a,b) a<b?b:a
#define min(a,b) a<b?a:b
using namespace std;
fstream fin("lca.in",ios::in);
fstream fout("lca.out",ios::out);
using namespace std;
int *Fii[NMax],n,m;
int euler[2*NMax][2],poz=0,lg;
int pozitie[NMax];
int *M[2*NMax];
void Citire()
{
int tata;
fin>>n>>m;
for(int i=1;i<=n;i++)
{
Fii[i]=(int*)malloc(sizeof(int));
Fii[i][0]=0;
}
for(int i=2;i<=n;i++)
{
fin>>tata;
Fii[tata][0]++;
Fii[tata]=(int*)realloc(Fii[tata],(Fii[tata][0]+1)*sizeof(int));
Fii[tata][Fii[tata][0]]=i;
}
}
void Euler(int nod,int nivel)
{
euler[poz][0]=nod;
euler[poz++][1]=nivel;
for( int i = 1; i <= Fii[nod][0]; i++ )
{
Euler(Fii[nod][i],nivel+1);
euler[poz][0]=nod;
euler[poz++][1]=nivel;
}
}
void Process()
{
int i,j;
for(int i=0;i<lg;i++)
{
M[i]=(int*)malloc((log2(lg-i)+1)*sizeof(int));
M[i][0]=i;
}
for(j=1;1<<j<=lg;j++)
for(i=0;i+(1<<j)-1<lg;i++)
if(euler[M[i][j-1]][1]<euler[M[i+(1<<(j-1))][j-1]][1])
M[i][j]=M[i][j-1];
else M[i][j]=M[i+(1<<(j-1))][j-1];
}
int RMQ(int i,int j)
{
int k=(int)log2(j-i+1);
if(euler[M[i][k]][1]<=euler[M[j-(1<<k)+1][k]][1])
return euler[M[i][k]][0];
else return euler[M[j-(1<<k)+1][k]][0];
}
void SolveQueries()
{
int u,v;
for(int i=0;i<2*n-1;i++)
{
pozitie[euler[i][0]]=i;
}
for(int i=0;i<m;i++)
{
fin>>u>>v;
fout<<RMQ(min(pozitie[u],pozitie[v]),max(pozitie[u],pozitie[v]))<<"\n";
}
}
void FreeMemory()
{
for(int i=1;i<=n;i++)
free(Fii[i]);
for(int i=0;i<lg;i++)
free(M[i]);
}
int main()
{
Citire();
Euler(1,0);
lg=2*n-1;
Process();
SolveQueries();
FreeMemory();
fin.close();
fout.close();
return 0;
}