Pagini recente » Cod sursa (job #659236) | Cod sursa (job #1599399) | Cod sursa (job #1503662) | Cod sursa (job #501160) | Cod sursa (job #2929720)
#include <fstream>
#include <iostream>
#include <vector>
#include <cmath>
#define NMAX 100002
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int block_sz;
int level[NMAX];
int parent[NMAX];
int jump_parent[NMAX];
vector<int> V[NMAX];
int n, m;
void DFS(int curr, int prev){
level[curr] = level[prev] + 1;
parent[curr] = prev;
if(level[curr] % block_sz == 0){
jump_parent[curr] = parent[curr];
}
else{
jump_parent[curr] = jump_parent[prev];
}
for(int i=0; i<V[curr].size(); i++){
if(V[curr][i] != prev){
DFS(V[curr][i], curr);
}
}
}
int LCANaive(int u, int v){
if(u == v){
return u;
}
if(level[u] > level[v])
swap(u, v);
v = parent[v];
return LCANaive(u, v);
}
int LCASqrt(int u, int v){
while(jump_parent[u] != jump_parent[v]){
if(level[u] > level[v])
swap(u, v);
v = jump_parent[v];
}
return LCANaive(u, v);
}
void preprocess(int n){
block_sz = sqrt(n);
level[0] = -1;
DFS(1, 0);
}
int mxLevel = -1; bool viz[NMAX] = {false};
void computeMaxLevel(int node, int level){
mxLevel = max(mxLevel, level);
viz[node] = true;
for(int i=0; i<V[node].size(); i++){
if(viz[V[node][i]] == false){
computeMaxLevel(V[node][i], level+1);
}
}
}
int main()
{
fin >> n >> m;
parent[1] = 0;
for(int i=2; i<=n; i++){
int ant;
fin >> ant;
parent[i] = ant;
V[ant].push_back(i);
V[i].push_back(ant);
}
computeMaxLevel(1, 0);
preprocess(mxLevel);
for(int q=1; q<=m; q++){
int node1, node2;
fin >> node1 >> node2;
fout << LCASqrt(node1, node2) << '\n';
}
return 0;
}