Pagini recente » Cod sursa (job #1036437) | Cod sursa (job #256847) | Cod sursa (job #1540053) | Cod sursa (job #224249) | Cod sursa (job #2031138)
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;
const int Maxn = 1e5 + 1e3;
vector <int> gr[Maxn];
vector <int> euler;
int poz[Maxn];
int dp[Maxn<<1][20];
int logg[Maxn<<1];
int nivel[Maxn];
ifstream f("lca.in");
ofstream g("lca.out");
void dfs(int node, int lvl){
nivel[node] = lvl;
euler.push_back(node);
poz[node] = euler.size()-1;
for(auto x : gr[node]){
dfs(x, lvl+1);
euler.push_back(node);
}
}
int query(int a, int b){
if(a > b) swap(a, b);
int l = logg[b-a];
if(nivel[dp[a][l]] < nivel[dp[b-(1<<l)][l]])
return dp[a][l];
return dp[b-(1<<l)][l];
}
int main(){
int n, m;
f >> n >> m;
for(int i = 2; i <= n; ++ i){
int a;
f >> a;
gr[a].push_back(i);
}
for(int i = 2; i <= 2*n+100; ++ i){
logg[i] = logg[i>>1]+1;
}
dfs(1, 1);
for(int i = 0; i < euler.size()-1; ++ i){
if(nivel[euler[i]] < nivel[euler[i+1]]){
dp[i][0] = euler[i];
}else dp[i][0] = euler[i+1];
}
for(int j = 1; j <= logg[n]; ++ j){
for(int i = 0; i < euler.size(); ++ i){
if(i + (1<<j) > euler.size()-1) break;
if(nivel[dp[i][j-1]] < nivel[dp[i+(1<<j-1)][j-1]]){
dp[i][j] = dp[i][j-1];
}else dp[i][j] = dp[i+(1<<j-1)][j-1];
}
}
for(int i = 0; i < m; ++ i){
int a, b;
f >> a >> b;
if(a == b) g << a << '\n';
else g << query(poz[a], poz[b]) << '\n';
}
return 0;
}