Pagini recente » Cod sursa (job #2628749) | Cod sursa (job #713706) | Cod sursa (job #452379) | Cod sursa (job #1143953) | Cod sursa (job #3213542)
#include <bits/stdc++.h>
#define NMAX 100001
using namespace std;
ifstream f ("lca.in");
ofstream g ("lca.out");
int n, m, k, lk;
vector<int> vecini[NMAX];
vector<int> par, first, depth;
vector<bool> viz;
vector< vector<int> > mini;
void parcurgereEul(int nod, int d){
par.push_back(nod);
depth.push_back(d);
first[nod] = par.size() - 1;
viz[nod] = true;
for(auto vecin : vecini[nod])
if(!viz[vecin]){
parcurgereEul(vecin, d + 1);
par.push_back(nod);
depth.push_back(d);
}
}
void check(){
for(int i = 1; i <= n; i ++)
g << first[i] << " ";
}
void createRmq(){
for(int i = 0; i < k; i ++)
mini[i][0] = i;
for(int len = 1; len <= lk; len ++){
for(int st = 0; st + (1 << len) - 1 < k; st ++){
int dr = st + (1 << len) - 1;
int mid = (st + dr) / 2 + 1;
if(depth[mini[st][len - 1]] < depth[mini[mid][len - 1]])
mini[st][len] = mini[st][len - 1];
else mini[st][len] = mini[mid][len - 1];
}
}
}
int sol(int st, int dr){
int len = (dr - st + 1);
int lenL = log2(len);
int i = st;
int j = dr - (lenL) + 1;
if(depth[mini[i][lenL]] < depth[mini[j][lenL]])
return par[mini[i][lenL]];
else return par[mini[j][lenL]];
}
int main()
{
f >> n >> m;
for(int i = 1; i <= n - 1; i ++){
int x;
f >> x;
vecini[x].push_back(i + 1);
vecini[i + 1].push_back(x);
}
viz = vector<bool>(n + 1, false);
first = vector<int>(n + 1, 0);
parcurgereEul(1, 0);
//check();
k = par.size();
lk = log2(k);
mini = vector< vector<int> >(k, vector<int>(lk + 1));
createRmq();
for(int i = 1; i <= m; i ++){
int x, y;
f >> x >> y;
int st = first[x];
int dr = first[y];
if(st > dr) swap(st, dr);
g << sol(st, dr) << '\n';
}
return 0;
}