Pagini recente » Cod sursa (job #8827) | Cod sursa (job #50585) | Cod sursa (job #366765) | Cod sursa (job #943388) | Cod sursa (job #1473736)
#include <iostream>
#include <vector>
#include <fstream>
#define NMax 100015
using namespace std;
int n,m, nivel[NMax*32], E[NMax*32],k,prima_aparitie[NMax];
int a[20][NMax*32];// pentru rmq
vector <int> v[NMax];
// bag nod crt fii sai (samd) si apoi radacina
fstream f,g;
void parcurgere_Euler( int nod, int nivel_crt)
{
E[++k] = nod;
nivel[k] = nivel_crt;
prima_aparitie[nod] = k; // unde se gaseste prima aparite a nodului pozitia k
int i;
for (i = 0 ; i < v[nod].size(); i++)
{
parcurgere_Euler(v[nod][i], nivel_crt+1);
E[++k] = nod;
nivel[k] = nivel_crt;
}
}
void read()
{
int i, tata;
f>>n>>m;
for (i = 2 ; i <= n ; i++)
{
f>>tata;
v[tata].push_back(i);
}
}
void range_minimum_query()
{
//a[i][j] = min (E[j],....E[j+2^i-1]
// a[i][j] = min(a[i-1][j],a[i-1][j + (1<<(i-1)) ]
// o sa tin minte indicele unde se afla acel minim
int i,j;
for ( i = 1 ; i <= k ; i++ )
a[0][i] = i;
for (i = 1; (1<<i)<=k ; i++)
for ( j = 1 ; j+(1<<i)<=k ; j++)
{
if (nivel[a[i-1][j]] < nivel[a[i-1][j + (1<<(i-1)) ]])
a[i][j] = a[i-1][j];
else
a[i][j] = a[i-1][j + (1<<(i-1)) ];
}
}
int solve( int nod1, int nod2)
{
int x = prima_aparitie[nod1];
int y = prima_aparitie[nod2];
if (y < x )
swap(x,y);
int dist = y-x ;
int putere = 0;
while ( ( 1<<(putere + 1) ) <= dist )
putere++;
if ( nivel[ a[putere][x] ] < nivel[ a[putere][y-(1<<putere)+1] ])
return E[a[putere][x]];
else
return E[a[putere][y-(1<<putere)+1]];
}
int main()
{
int x,y;
f.open("lca.in",ios::in);
g.open("lca.out",ios::out);
read();
parcurgere_Euler(1,0);
range_minimum_query();
for (int i = 1; i <= m ; i++)
{
f>>x>>y;
g<<solve(x, y)<<"\n";
}
}