Pagini recente » Cod sursa (job #980657) | Cod sursa (job #1795629) | Cod sursa (job #2659922) | Cod sursa (job #980383) | Cod sursa (job #2701017)
#include <iostream>
#include <fstream>
#include <vector>
const int N=100000;
const int LOG=17;
std::ifstream in("lca.in");
std::ofstream out("lca.out");
std::vector<int> tree[N+1];
/// aici parent[i][j] va fi al 2^j-lea stramos al lui i
int parent[N+1][LOG+1];
int depth[N+1];
void preprocess(int n)
{
//avem deja coloana 0, care reprezinta parintele direct al fiecarui punct
for(int i=1; i<=LOG; i++)
{
for(int node=1; node<=n; node++)
{
if(parent[node][i-1]!=0)
{
parent[node][i]=parent[ parent[node][i-1] ][ i-1 ];
}
}
}
}
int lca(int u, int v)
{
// v va fi mai adanc ca u
if(depth[v]<depth[u])
{
std::swap(u, v);
}
//aducem u si v la acelasi nivel
int diferenta=depth[v]-depth[u];
for(int i=0; i<=LOG; i++)
{
if((diferenta>>i)&1)
{
v=parent[v][i];
}
}
if(u==v) return u;
for(int i=LOG; i>=0; i--)
{
if(parent[u][i]!=parent[v][i])
{
u=parent[u][i];
v=parent[v][i];
}
}
return parent[u][0];
}
int main()
{
int n, m, x, u, v;
in>>n>>m;
for(int i=2; i<=n; i++)
{
in>>x;
tree[x].push_back(i);
depth[i]=depth[x]+1;
parent[i][0]=x;
}
for(int i=1; i<=m; i++)
{
in>>u>>v;
out<<lca(u, v)<<"\n";
}
}