Pagini recente » Infoarena Monthly 2012 - Runda 2, Clasament | Cod sursa (job #2516562) | Borderou de evaluare (job #528025) | Cod sursa (job #2984100) | Cod sursa (job #2928205)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
#define NMAX (int)1e5
#define MAXLOG 17
int start[NMAX + 5], endd[NMAX + 5];
int up[NMAX + 5][MAXLOG + 1];
int timer, logg2;
vector<int> G[NMAX + 5];
void DFS(int node, int father) {
start[node] = ++timer;
up[node][0] = father;
for (int i = 1; i <= logg2; i++) {
up[node][i] = up[up[node][i - 1]][i - 1];
}
for (auto child : G[node]) {
if (child != father) {
DFS(child, node);
}
}
endd[node] = ++timer;
}
bool is_stramos(int node1, int node2) {
return start[node1] <= start[node2] && endd[node1] >= endd[node2];
}
int LCA(int node1, int node2) {
if (is_stramos(node1, node2))
return node1;
if (is_stramos(node2, node1))
return node2;
for (int i = logg2; i >= 0; i--) {
if (!is_stramos(up[node1][i], node2)) {
node1 = up[node1][i];
}
}
return up[node1][0];
}
void preprocess(int n) {
timer = 0;
logg2 = log2(n);
DFS(1, 1);
}
ifstream cin("lca.in");
ofstream cout("lca.out");
int main()
{
int n, m, node, node1, node2;
cin >> n >> m;
for (int i = 1; i <= n - 1; i++) {
cin >> node;
G[node].push_back(i + 1);
}
preprocess(n);
for (int i = 1; i <= m; i++) {
cin >> node1 >> node2;
cout << LCA(node1, node2) << "\n";
}
}