Pagini recente » Cod sursa (job #1774605) | Cod sursa (job #77457) | Cod sursa (job #2354670) | Cod sursa (job #2475813) | Cod sursa (job #2155037)
#include <fstream>
#include <vector>
#define MAX 100005
#define LOG 25
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
vector <int> G[MAX];
vector <int> euler;
vector <int> eulerNivel;
int P[MAX],nivel[MAX];
int prima[MAX];
pair <int,int> minim[LOG][MAX];
int n,m;
void dfs(int nod)
{
euler.push_back(nod);
//eulerNivel.push_back(nivel[nod]);
prima[nod]=euler.size()-1;
for (auto v: G[nod])
{
nivel[v]=nivel[nod]+1;
dfs(v);
euler.push_back(nod);
}
}
void getRMQ()
{
/// lucram pe nivelurile din euler
for (int i=0; i<euler.size(); i++)
minim[0][i]={nivel[euler[i]],euler[i]};
for (int b=1; (1<<b)<euler.size(); b++)
{
for (int i=0; i<euler.size(); i++)
{
if (minim[b-1][i].first<minim[b-1][(i+(1<<(b-1)))].first)
minim[b][i].second=minim[b-1][i].second;
else
minim[b][i].second=minim[b-1][(i+(1<<(b-1)))].second;
minim[b][i].first=min(minim[b-1][i].first,
minim[b-1][(i+(1<<(b-1)))].first);
}
}
}
int valMin(int a,int b)
{
/// pozitia pe care se afla minimul in [a,b]
if (a==b)
return a;
//int l=b-a+1;
int p=0;
while (a+(1<<p)<=b)
p++;
p--;
///int rez=min(minim[p][a],minim[p][b-(1<<p)]);
if (minim[p][a].first<minim[p][b-(1<<p)].first)
return minim[p][a].second;
return minim[p][b-(1<<p)].second;
}
int main()
{
fi>>n>>m;
for (int i=2; i<=n; i++)
fi>>P[i],G[P[i]].push_back(i);
dfs(1);
//for (auto x: euler)
//fo<<nivel[x]<<" ";
getRMQ();
while (m--)
{
int a,b;
fi>>a>>b;
if (a==b)
{
fo<<a<<"\n";
continue;
}
if (prima[a]>prima[b])
swap(a,b);
fo<<valMin(prima[a],prima[b])<<"\n";
}
return 0;
}