Pagini recente » Cod sursa (job #3146807) | Cod sursa (job #978544) | Cod sursa (job #313106) | Cod sursa (job #2203736) | Cod sursa (job #1182930)
#include <fstream>
#include <vector>
using namespace std;
const int N = 1 + 1e5, LGLG = 5;
int T[N], son[N], head[LGLG][N], depth[N], heavyDepth[N], n;
vector<int> tree[N];
int dfs(int x){
int weight = 0, best = -1, val;
for (auto it = tree[x].begin() ; it != tree[x].end() ; it++){
depth[*it] = 1 + depth[x];
val = dfs(*it);
weight += val;
if (best < val){
best = val;
son[x] = *it;
}
}
return weight;
}
void build(int x, int H, int D){
heavyDepth[x] = D;
head[0][x] = H;
for (auto it = tree[x].begin() ; it != tree[x].end() ; it++)
if ( son[x] != *it )
build( *it, *it, D + 1 );
else
build( *it, H, D );
}
int heavyAncestor(int x, int nr){
for (int i = 31 - __builtin_clz(nr) ; i >= 0 ; i--)
if (nr & (1 << i)){
nr ^= 1 << i;
x = T[ head[i][x] ];
}
return x;
}
int lca(int x, int y){
if ( heavyDepth[x] < heavyDepth[y] )
y = heavyAncestor(y, heavyDepth[y] - heavyDepth[x]);
else
x = heavyAncestor(x, heavyDepth[x] - heavyDepth[y]);
for (int i = LGLG - 1 ; i >= 0 ; i--)
if ( head[i][x] != head[i][y] ){
x = T[ head[i][x] ];
y = T[ head[i][y] ];
}
return depth[x] < depth[y] ? x : y;
}
int main(){
int nrQ, x, y;
ifstream in("lca.in");
in >> n >> nrQ;
for (int i = 2 ; i <= n ; i++){
in >> T[i];
tree[ T[i] ].push_back(i);
}
dfs(1);
build(1, 1, 1);
for (int i = 1 ; i < LGLG ; i++)
for (int j = 1 ; j <= n ; j++)
head[i][j] = head[i - 1][ T[ head[i - 1][j] ] ];
ofstream out("lca.out");
while (nrQ--){
in >> x >> y;
out << lca(x, y) << '\n';
}
in.close();
out.close();
return 0;
}