Pagini recente » Cod sursa (job #1611249) | Cod sursa (job #2254348) | Cod sursa (job #833054) | Cod sursa (job #1964706) | Cod sursa (job #3306464)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int Nmax = 100005;
int n, m, lenE, log2[2*Nmax+5], first[2*Nmax+5];
vector<int> L[Nmax];
vector<pair<int, int>> E; // first = depth && second = nodul;
pair<int, int> dp[2*Nmax+5][25];
// dp[i][j] = elem cu depth minim de pe intervalul [i, i + 2^j - 1]
// continand first = depth && second = nodul
void dfs(int nod, int depth){
E.push_back({depth, nod});
if(!first[nod]){
first[nod] = E.size() - 1;
}
for(auto son : L[nod]){
dfs(son, depth+1);
E.push_back({depth, nod});
}
}
void preCalc(){
log2[1] = 0;
for(int i = 2; i <= 2*Nmax; i++){
log2[i] = log2[i/2] + 1;
}
}
void RMQ(){
for(int i = 0; i < lenE; i++){
dp[i][0] = E[i];
}
for(int p = 1; (1 << p) < lenE; p++){
for(int i = 0; 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 len = dr - st + 1;
int p = log2[len];
auto sol = min(dp[st][p], dp[dr - (1 << p) + 1][p]);
return sol.second;
}
int main(){
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> m;
for(int i = 2; i <= n; i++){
int aux;
fin >> aux;
L[aux].push_back(i);
}
preCalc();
dfs(1, 0);
lenE = E.size();
RMQ();
while(m--){
int x, y;
fin >> x >> y;
x = first[x];
y = first[y];
if(x > y){
swap(x, y);
}
fout << query(x, y) << "\n";
}
return 0;
}