Pagini recente » Cod sursa (job #2338469) | Cod sursa (job #728071) | Cod sursa (job #159914) | Cod sursa (job #2277697) | Cod sursa (job #2657145)
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
struct nod
{
int info;
nod * urm;
}*vecin[100001];
nod * prim[100001];
const int INFINIT=100000;
int e[200001], tt[100001], poz[100001], lev[100001];
int mn[19][200001], pozmin[19][200001];
int lg, log;
void reprez(int x)
{
e[++lg]=x;
poz[x]=lg;
nod * t = prim[x];
while(t!=NULL)
{
lev[t->info] = lev[x]+1;
reprez(t->info);
e[++lg]=x;
t=t->urm;
}
}
int lca (int x, int y)
{
int rez, salv, i;
if(y<x) swap(x, y);
rez=INFINIT;
for(i=log; i>=0; i--)
{
if( (y-x) & (1<<i) )
{
rez=min(rez, mn[i][x]);
if(rez==mn[i][x]) salv=pozmin[i][x];
x+=(1<<i);
}
}
return e[salv];
}
int main()
{
//mai intai construiesc vectorul e[] ce reprezinta reprezentarea euler
int n, k, i, j;
fin>>n>>k;
for(i=2; i<=n; i++)
{
fin>>tt[i];
//il adaug pe i la fiii lui tt[i];
nod * aux = new nod;
aux->info=i;
aux->urm=NULL;
if(prim[ tt[i] ]==NULL)
{
prim[ tt[i] ]=aux;
vecin[ tt[i] ]=aux;
}
else
{
vecin[ tt[i] ]->urm=aux;
vecin[ tt[i] ]=aux;
}
}
reprez(1);
for(i=1; i<=lg; i++)
{
mn[0][i]=min(lev[ e[i] ], lev[ e[i+1] ]);
if(mn[0][i]==lev[ e[i+1] ])pozmin[0][i]=i+1;
else pozmin[0][i]=i;
}
for(log=1; (1<<log)<lg; log++);
for(i=1; i<=log; i++)
{
for(j=1; j<=lg; j++)
{
mn[i][j] = min(mn[i-1][j], mn[i-1][j+(1<<(i-1))]);
if(mn[i][j]==mn[i-1][j]) pozmin[i][j]=pozmin[i-1][j];
else pozmin[i][j]=pozmin[i-1][j+(1<<(i-1))];
}
}
int x, y;
for(i=1; i<=k; i++)
{
fin>>x>>y;
fout<<lca(poz[x], poz[y])<<"\n";
}
}