Pagini recente » Cod sursa (job #442708) | Cod sursa (job #2942935) | Cod sursa (job #477915) | Cod sursa (job #2757704) | Cod sursa (job #1378651)
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
ifstream in("lca.in");
const int kNMax = 100010, kLgMax = 18;
int n, m, prima_aparitie[kNMax], lg[2 * kNMax], rmq[kLgMax][2 * kNMax];
vector<int> G[kNMax];
vector<pair<int, int> > euler;
void Citire() {
int x;
in >> n >> m;
for (int i = 2; i <= n; ++i) {
in >> x;
G[x].push_back(i);
}
}
void Dfs(int nod, int nivel) {
prima_aparitie[nod] = euler.size();
euler.push_back(make_pair(nod, nivel));
for (int i = 0; i < G[nod].size(); ++i) {
int vecin = G[nod][i];
Dfs(vecin, nivel + 1);
euler.push_back(make_pair(nod, nivel));
}
}
void ReprezentareEuler() {
euler.push_back(make_pair(0, 0));
Dfs(1, 0);
}
void PrecalculareLg() {
n *= 2;
for (int i = 2; i <= n; ++i)
lg[i] = lg[i / 2] + 1;
}
void Rmq() {
for (int i = 1; i <= n; ++i)
rmq[0][i] = i;
for (int i = 1; (1 << i) <= n; ++i)
for (int j = 1; j + (1 << i) - 1 <= n; ++j)
if (euler[rmq[i - 1][j]].second < euler[rmq[i - 1][j + (1 << (i - 1))]].second )
rmq[i][j] = rmq[i - 1][j];
else
rmq[i][j] = rmq[i-1][j + (1 << (i - 1))];
}
void Initializare() {
ReprezentareEuler();
PrecalculareLg();
Rmq();
}
int lca(int x, int y) {
x = prima_aparitie[x];
y = prima_aparitie[y];
if (x > y)
swap(x, y);
int d = y - x + 1;
if (euler[rmq[lg[d]][x]].second < euler[rmq[lg[d]][y - (1 << lg[d]) + 1]].second)
return euler[rmq[lg[d]][x]].first;
else
return euler[rmq[lg[d]][y - (1 << lg[d]) + 1]].first;
}
void Query() {
ofstream out ("lca.out");
int x, y;
while (m--) {
in >> x >> y;
out << lca(x, y) << '\n';
}
in.close();
out.close();
}
void Solve() {
Initializare();
Query();
}
int main() {
Citire();
Solve();
return 0;
}