Pagini recente » Cod sursa (job #1418606) | Cod sursa (job #2926459) | Cod sursa (job #609678) | Cod sursa (job #3213277) | Cod sursa (job #1922335)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define maxN 100010
#define maxLog 20
int n,m,nr_rmq;
int euler[maxN*2],lvl[maxN*2],lg[maxN*2],first[maxN];
int rmq[maxLog][maxN*2];
vector <int> v[maxN];
void readData()
{
fin>>n>>m;
for (int f,i=2; i<=n; ++i)
{
fin>>f;
v[f].push_back(i);
}
}
void DFS(int nod, int lv)
{
euler[++nr_rmq]=nod;
lvl[nr_rmq]=lv;
first[nod]=nr_rmq;
for (auto it:v[nod])
{
DFS(it,lv+1);
euler[++nr_rmq]=nod;
lvl[nr_rmq]=lv;
}
}
inline int minimByLevel(int lvl[], int a, int b)
{
if (lvl[a]<lvl[b]) return a;
return b;
}
void buildRMQ()
{
lg[1]=0;
for (int i=2; i<=nr_rmq; ++i)
lg[i]=lg[i/2]+1;
for (int i=1; i<=nr_rmq; ++i)
rmq[0][i]=i;
for (int i=1; (1<<i)<=nr_rmq; ++i)
for (int j=1; j<=nr_rmq-(1<<i)+1; ++j)
{
rmq[i][j]=minimByLevel(lvl,rmq[i-1][j],rmq[i-1][j+(1<<i-1)]);
}
}
int LCA(int x, int y)
{
int a=first[x], b=first[y];
if (a>b) swap(a,b);
int diff,line,s;
diff=b-a+1;
line=lg[diff];
s=diff-(1<<line);
return euler[minimByLevel(lvl,rmq[line][a],rmq[line][a+s])];
}
int main()
{
readData();
DFS(1,0);
buildRMQ();
while (m--)
{
int x,y;
fin>>x>>y;
fout<<LCA(x,y)<<'\n';
}
return 0;
}