Pagini recente » Cod sursa (job #1473282) | Cod sursa (job #81781) | Cod sursa (job #2544991) | Cod sursa (job #614207) | Cod sursa (job #2084816)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout ("lca.out");
const int N_MAX = 100005;
int n, m;
int euler[3 * N_MAX], ne;
int poz[N_MAX], niv[N_MAX];
int dp[30][3 * N_MAX];
vector<int> vec[N_MAX];
void make_euler(int nod, int nivel){
euler[++ne] = nod;
niv[ne] = nivel;
poz[nod] = ne;
for(auto v : vec[nod]){
make_euler(v, nivel + 1);
euler[++ne] = nod;
niv[ne] = nivel;
}
}
void rmq(){
for(int level = 1; level <= log2(ne); ++level)
for(int j = 1; j<=ne; ++j)
if(niv[dp[level-1][j]] < niv[dp[level-1][j + (1 << (level-1))]])
dp[level][j] = dp[level-1][j];
else
dp[level][j] = dp[level-1][j + (1 << (level-1))];
}
int query(int a, int b){
int nivel = log2(b-a+1);
if(niv[dp[nivel][a]] <= niv[dp[nivel][b - (1 << nivel) + 1]])
return dp[nivel][a];
else
return dp[nivel][b-(1<<nivel) + 1];
}
int lca(int a, int b){
int lo = min(a, b);
int hi = max(a, b);
return euler[query(lo, hi)];
}
int main()
{
fin >> n >> m;
for(int i = 2, x; i<=n; ++i){
fin >> x; vec[x].push_back(i);
}
make_euler(1, 0);
for(int i = 1; i <=ne; ++i)
dp[0][i] = i;
rmq();
while(m--){
int a, b; fin >> a >> b;
fout << lca(poz[a],poz[b]) << "\n";
}
return 0;
}