Pagini recente » Cod sursa (job #2562867) | Cod sursa (job #3322734) | Cod sursa (job #3346129) | Cod sursa (job #3301725) | Cod sursa (job #3306399)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
const int Nmax = 100001;
int n, m, firstApp[Nmax], depth[Nmax], log2[Nmax], dp[Nmax][22], lenE;
//dp[i][j] = nodul cu depth minim pe [i, i + 2^j - 1] pe vectorul E
vector<int> L[Nmax], E;
void dfs(int nod){
E.push_back(nod);
firstApp[nod] = E.size() - 1;
for(auto son : L[nod]){
depth[son] = depth[nod] + 1;
dfs(son);
E.push_back(nod);
}
}
void preCalc(){
log2[1] = 0;
for(int i = 2; i <= n; i++){
log2[i] = log2[i/2] + 1;
}
}
void RMQ(){
for(int i = 0; i < lenE; i++){
dp[i][0] = E[i];
}
for(int p = 1; (1 << p) < lenE; p++){
for(int i = 0; i < lenE; i++){
dp[i][p] = dp[i][p-1];
int j = i + (1 << (p-1));
if(j < lenE && (depth[dp[i][p]]> depth[dp[j][p-1]])){
dp[i][p] = dp[j][p-1];
}
}
}
}
int solve(int u, int v){
int poz1 = firstApp[u];
int poz2 = firstApp[v];
if(poz1 > poz2){
swap(poz1, poz2);
}
int dif = poz2 - poz1 + 1;
int p = log2[dif];
int min1 = dp[poz1][p];
int min2 = dp[poz2 - (1 << p) + 1][p];
if(depth[min1] < depth[min2]){
return min1;
}
return min2;
}
int main()
{
ifstream fin("lca.in");
ofstream fout("lca.out");
fin >> n >> m;
for(int i = 2; i <= n; i++){
int aux;
fin >> aux;
L[aux].push_back(i);
}
depth[1] = 0;
dfs(1);
preCalc();
lenE = E.size();
RMQ();
while(m--){
int u, v;
fin >> u >> v;
fout << solve(u, v) << "\n";
}
return 0;
}