Pagini recente » Cod sursa (job #1208063) | Cod sursa (job #1490607) | Istoria paginii runda/miada | Cod sursa (job #1839342) | Cod sursa (job #3032192)
#include <fstream>
#include <iostream>
#include <vector>
#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 A[MMAX][LOGMAX];
vector<vector<int>> sons;
void read() {
int nr;
fin >> N >> M;
sons.resize(N + 1);
for (int i = 2; i <= N; ++i) {
fin >> nr;
sons[nr].push_back(i);
}
}
void setP() {
for (int i = 1; i <= N; ++i) {
p[i] = -1;
}
}
vector<int> v;
void createEuler(int nod) {
if (p[nod] == -1) {
p[nod] = v.size();
}
v.push_back(nod);
for (auto& son : sons[nod]) {
createEuler(son);
v.push_back(nod);
}
}
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 log2(int nr) {
int r = 0;
while ((1 << r) <= nr) {
++r;
}
return r - 1;
}
int query(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 = query(p[b], p[a]);
}
else
ans = query(p[a], p[b]);
fout << v[ans] << "\n";
}
}
int main()
{
read();
setP();
createEuler(1);
init();
solve();
return 0;
}