Pagini recente » Cod sursa (job #1979338) | Cod sursa (job #1206260) | Cod sursa (job #986485) | Cod sursa (job #2089710) | Cod sursa (job #2766351)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, cnt;
vector<int> v[200100];
int first[200200];
struct euler
{
int nod;
int nivel;
};
euler parcurgere[200200];
int nivel[200100];
int logaritm[200200];
int rmq[200100][19]; /// pozitia corespunzatoare in parcurgerea euler celui mai mic nivel
void dfs(int nod, int tata)
{
nivel[nod] = nivel[tata] + 1;
parcurgere[++cnt].nod = nod;
parcurgere[cnt].nivel = nivel[nod];
for(int it = 0; it != v[nod].size(); it++)
{
dfs(v[nod][it], nod);
parcurgere[++cnt].nod = nod;
parcurgere[cnt].nivel = nivel[nod];
}
}
int Merge(int a, int b)
{
if(parcurgere[a].nivel < parcurgere[b].nivel)
{
return a;
}
else
return b;
}
int lca(int a, int b)
{
if(a > b)
swap(a,b);
int logg = logaritm[b-a+1];
return Merge(rmq[a][logg], rmq[b - (1 << logg) + 1][logg]);
}
int main()
{
fin >> n >> m;
for(int i = 2; i <= n; i ++)
{
int val;
fin >> val;
v[val].push_back(i);
}
dfs(1, 0);
for(int i = 1; i <= cnt; i ++)
{
if(first[parcurgere[i].nod] == 0)
{
first[parcurgere[i].nod] = i;
}
}
for(int i = 1; i <= cnt; i ++)
{
rmq[i][0] = i;
}
for(int i = 2; i <= cnt; i ++)
{
logaritm[i] = logaritm[i/2] + 1;
}
for(int j = 1; (1 << j) <= cnt; j ++)
{
for(int i = 1; i + (1 << j) - 1 <= cnt; i ++)
{
rmq[i][j] = Merge(rmq[i][j-1], rmq[i + (1 << (j-1))][j-1]);
}
}
///fout << parcurgere[lca(first[1],first[1])].nod;
///fout << '\n';
while(m--)
{
int l, r;
fin >> l >> r;
fout << parcurgere[lca(first[l], first[r])].nod << '\n';
}
return 0;
}