Pagini recente » Cod sursa (job #2007471) | Cod sursa (job #1159925) | Monitorul de evaluare | Cod sursa (job #683683) | Cod sursa (job #2574037)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nmax = 100005;
int n, m;
vector <int> g[nmax];
int euler[2*nmax], nivel[2*nmax], primap[nmax], k;
int sp[2*nmax][30];
inline void read()
{
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
int a;
fin >> a;
g[a].push_back(i);
}
}
inline void dfs(int nod,int tata, int niv)
{
euler[++k] = nod;
nivel[k] = niv;
if (primap[nod] == 0)
primap[nod] = k;
for (auto fiu : g[nod])
{
if (fiu == tata)
continue;
dfs(fiu, nod, niv+1);
euler[++k] = nod;
nivel[k] = niv;
}
}
inline int rmq(int a, int b)
{
if (b < a)
swap(a, b);
int l = b-a+1;
int k = log2(l)+1;
if (nivel[sp[a][k]] < nivel[sp[b - (1 << (k-1))+1][k]])
return sp[a][k];
return sp[b-(1 << (k-1))+1][k];
}
inline void gettable()
{
dfs(1, 0, 1);
for (int i = 1; i <= k; i++)
sp[i][1] = i;
for (int j = 2; (1 << (j-1)) <= k; j++)
for (int i = 1; i + (1 << (j-1)) - 1 <= k; i++)
if (nivel[sp[i][j-1]] < nivel[sp[i + (1 << (j-2))][j-1]])
sp[i][j] = sp[i][j-1];
else
sp[i][j] = sp[i+(1 << (j-2))][j-1];
}
inline int lca(int a, int b)
{
return euler[rmq(primap[a], primap[b])];
}
int main()
{
read();
gettable();
while (m--)
{
int a, b;
fin >> a >> b;
fout << lca(a, b) << "\n";
}
return 0;
}