Pagini recente » Cod sursa (job #3203407) | Cod sursa (job #3163364) | Monitorul de evaluare | Cod sursa (job #1920503) | Cod sursa (job #2639739)
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <cmath>
const int NMAX=(int)1e5+1;
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
map<int, vector<int>> sons;
vector<pair<int, int>> euler;
int v[3*NMAX][20];
int first[NMAX];
void read(){
fin>>n>>m;
for(int i=2;i<=n;i++){
int x;
fin>>x;
sons[x].push_back(i);
}
}
void exec_euler(int dad = 1, int lvl = 0){
first[dad]=(int)euler.size();
euler.emplace_back(dad, lvl);
for(auto son : sons[dad]){
exec_euler(son, lvl+1);
euler.emplace_back(dad, lvl);
}
}
void exec_rmq(){
n = euler.size();
for(int i=0;i<n;i++)
v[i][0] = i;
int pow = 1;
for(int j=1;pow*2<=n;j++){
for(int i=0;i+pow*2-1<n;i++){
if(euler[v[i][j-1]].second<euler[v[i+pow][j-1]].second)
v[i][j] = v[i][j-1];
else
v[i][j] = v[i+pow][j-1];
}
pow*=2;
}
}
int min_rmq(int x, int y){
int lg = static_cast<int>(log2(y-x+1));
if(euler[v[x][lg]].second<euler[v[y-(1<<lg)+1][lg]].second)
return euler[v[x][lg]].first;
return euler[v[y-(1<<lg)+1][lg]].first;
}
void exec(){
int a, b;
while(m--){
fin>>a>>b;
a = first[a];
b = first[b];
if(b<a) swap(a, b);
fout<<min_rmq(a, b)<<'\n';
}
}
int main() {
read();
exec_euler();
exec_rmq();
exec();
return 0;
}