Pagini recente » Cod sursa (job #74727) | Cod sursa (job #2266945) | Cod sursa (job #3348983) | Cod sursa (job #1111353) | Cod sursa (job #3346445)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, k, euler[100001], niv[100001], first[100001], rmq[12][100001],
log2[100001], pow2[20];
vector<int> adj[100001];
void DFS(int x){
euler[++k] = x;
first[x] = k;
rmq[0][x] = x;
for (const auto& y: adj[x]){
niv[y] = niv[x] + 1;
DFS(y);
euler[++k] = x;
}
}
void construct_rmq(){
pow2[0] = 1;
for (int i = 1; i <= k; i ++){
if (i > 1)
log2[i] = log2[i >> 1] + 1;
if (i <= 20)
pow2[i] = pow2[i - 1] << 1;
}
///minimul dintre doua pozitii din parcurgerea euler a arborelui
for (int i = 1; i <= k; i ++)
rmq[0][i] = i;
for (int j = 1; pow2[j] <= k; j ++)
for (int i = 1; i + pow2[j] - 1 <= k; i ++){
int u = rmq[j - 1][i], v = rmq[j - 1][i + pow2[j - 1]];
if (niv[euler[u]] < niv[euler[v]])
rmq[j][i] = u;
else
rmq[j][i] = v;
}
}
int query(int l, int r){
if (l > r)
swap (l, r);
int d = r - l + 1;
int j = log2[d];
int pl = rmq[j][l], pr = rmq[j][r - pow2[j] + 1];
if (niv[euler[pl]] < niv[euler[pr]])
return pl;
else
return pr;
}
int lca(int x, int y){
int pos = query(first[x], first[y]);
return euler[pos];
}
int main()
{
fin >> n >> m;
for (int i = 2, x; i <= n; i ++){
fin >> x;
T[i] = x;
adj[x].push_back(i);
}
DFS(1);
construct_rmq();
while (m --){
int x, y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
}