Pagini recente » Cod sursa (job #29305) | Cod sursa (job #1318190) | Cod sursa (job #369021) | Cod sursa (job #117673) | Cod sursa (job #3258497)
#include <bits/stdc++.h>
#define NMAX 100005
#define MMAX 2000005
#define LOGMAX 25
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m, p[NMAX];
int x;
int A[MMAX][LOGMAX];
vector<vector<int>> sons;
vector<int> v;
void citeste(){ ///citesc arborele ca o lista de adiacenta a copiilor
fin >> n >> m;
sons.resize(n+1);
for(int i=2; i<=n; ++i){
fin >> x;
sons[x].push_back(i);
}
}
void setP(){
for(int i=2; i<=n; ++i){
p[i]=-1;
}
}
void eulerTour(int nod){
if(p[nod]==-1){ /// daca nodul nu a fost vizitat
p[nod]=v.size(); ///p[nod] retine prima aparitie a fiecarui nod in turul Euler
}
v.push_back(nod);
for (auto &son : sons[nod]){
eulerTour(son);
v.push_back(nod); /// v - retine turul Euler
}
}
void init() {
for (int i = 0; i < v.size(); ++i) {
A[i][0] = i;
}
for (int j = 1; (1 << j) <= v.size(); ++j) {
for (int i = 0; i + (1 << j) - 1 < v.size(); ++i) {
int p1 = A[i][j - 1];
int p2 = A[i + (1 << (j - 1))][j - 1];
if (v[p1] <= v[p2]) {
A[i][j] = p1;
} else {
A[i][j] = p2;
}
}
}
}
int RMQ(int i, int j) {
int k = log2(j - i + 1);
if (v[A[i][k]] <= v[A[j - (1 << k) + 1][k]]) {
return A[i][k];
}
return A[j - (1 << k) + 1][k];
}
void solve() {
int a, b, ans;
for (int i = 1; i <= m; ++i) {
fin >> a >> b;
if (p[a] > p[b]) {
ans = RMQ(p[b], p[a]);
} else {
ans = RMQ(p[a], p[b]);
}
fout << v[ans] << "\n";
}
}
int main()
{
citeste();
setP();
eulerTour(1);
init();
solve();
return 0;
}