Pagini recente » Cod sursa (job #2037346) | Cod sursa (job #817971) | Cod sursa (job #2299453) | Cod sursa (job #2193363) | Cod sursa (job #3306426)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int Nmax = 100005;
int n, m, top, log2[Nmax], first[Nmax];
bool viz[Nmax];
vector<int> L[Nmax];
vector<pair<int, int>> E;
pair<int, int> dp[Nmax][22];
//dp[i][j] = idx nodului cu depth min in E[] inc de la i cu lung 2^j
//first = niv, second = nodul
int lenE;
void preCalc(){
log2[1] = 0;
for(int i = 2; i <= Nmax; i++){
log2[i] = log2[i/2] + 1;
}
}
void dfs(int nod, int niv){
E.push_back({nod, niv});
if(!viz[nod]){
first[nod] = E.size() - 1;
viz[nod] = true;
}
for(auto vec : L[nod]){
dfs(vec, niv+1);
E.push_back({nod, niv});
}
}
void RMQ(){
for(int i = 0; i < lenE; i++){
dp[i][0] = {E[i].second , E[i].first};
}
for(int p = 1; (1 << p) <= lenE; p++){
for(int i = 1; i + (1 << (p-1)) <= lenE; i++){
dp[i][p] = min(dp[i][p-1], dp[i + (1 << (p-1))][p-1]);
}
}
}
int query(int st, int dr){
int l = dr - st + 1;
int p = log2[l];
int jum = (1 << p);
return min(dp[st][p], dp[dr - jum + 1][p]).second;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> m;
first[1] = -1;
for(int i = 2; i <= n; i++){
int aux;
fin >> aux;
L[aux].push_back(i);
first[i] = -1;
}
preCalc();
dfs(1, 0);
lenE = E.size();
RMQ();
while(m--){
int u, v;
fin >> u >> v;
u = first[u];
v = first[v];
if(u > v){
swap(u, v);
}
fout << query(u, v) << "\n";
}
return 0;
}