Pagini recente » Cod sursa (job #653705) | Cod sursa (job #570135) | Cod sursa (job #1060206) | Cod sursa (job #1791439) | Cod sursa (job #2858619)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<vector<int>> graf;
int n, m;
vector<pair<int, int>> eulerian;
vector<int> occurance;
int RMQ[200005][20];
void dfs(int nod, int nivel)
{
eulerian.push_back({nod, nivel});
// pozitia la ultimul elem
occurance[nod] = eulerian.size() - 1;
for(int i: graf[nod])
{
dfs(i, nivel + 1);
eulerian.push_back({nod, nivel});
}
}
void gen_RMQ()
{
for(int i = 0 ; i < eulerian.size(); i++)
{
//initializam cu valoarea acelui nod pt ca in RMQ tinem indici
RMQ[i][0] = i;
}
for(int i = 1; i <= log(eulerian.size()); i++)
{
for(int j = 0; j + (1 << i) < eulerian.size(); j++)
{
if(eulerian[RMQ[j][i - 1]].second < eulerian[RMQ[j + (1 << (i-1))][i - 1]].second)
{
RMQ[j][i] = RMQ[j][i - 1];
}
else
{
RMQ[j][i] = RMQ[j + (1 << (i-1))][i - 1];
}
}
}
}
void citire()
{
fin >> n >> m;
int tata;
graf = vector<vector<int>>(n + 1);
occurance = vector<int>(n + 1);
for(int i = 2; i <= n; i++)
{
fin >> tata;
graf[tata].push_back(i);
}
}
int main()
{
citire();
dfs(1,0);
gen_RMQ();
int n1, n2;
int sol;
int log_dist;
for(int i = 0; i < m ;i ++)
{
fin >> n1 >> n2;
// trebuie sa stim care e mai mare
if(occurance[n1] > occurance[n2])
{
log_dist = log(occurance[n1]-occurance[n2]);
// aflam minimul dintre cele 2 jumatati
if(eulerian[RMQ[occurance[n2]][log_dist]].second < eulerian[RMQ[occurance[n1] - (1 << log_dist)][log_dist]].second)
{
sol = RMQ[occurance[n2]][log_dist];
}
else
{
sol = RMQ[occurance[n1]-(1 << log_dist)][log_dist];
}
}
else
{
log_dist = log(occurance[n2]-occurance[n1]);
if(eulerian[RMQ[occurance[n1]][log_dist]].second < eulerian[RMQ[occurance[n2] - (1 << log_dist)][log_dist]].second)
{
sol = RMQ[occurance[n1]][log_dist];
}
else
{
sol = RMQ[occurance[n2] - (1 << log_dist)][log_dist];
}
}
fout << eulerian[sol].first << '\n';
}
}