Pagini recente » Cod sursa (job #3247351) | Utilizatori inregistrati la Infoarena Monthly 2014 - Runda 5 | Cod sursa (job #2260282) | Cod sursa (job #3277393) | Cod sursa (job #771612)
Cod sursa(job #771612)
#include <stdio.h>
#include <vector>
#include <cmath>
#define NMAX 100002
#define MMAX 4000004
#define LIMIT 25
using namespace std;
vector<int> nodes[NMAX];
vector< pair<int, int> > Euler;
int PMin[MMAX][LIMIT];
int Pos[NMAX];
void left_root_right(int node, int h) {
Euler.push_back(make_pair(node, h));
if (Pos[node] == 0) {
Pos[node] = Euler.size() - 1;
}
vector<int>::iterator it;
for (it = nodes[node].begin(); it != nodes[node].end(); it++) {
left_root_right(*it, h + 1);
Euler.push_back(make_pair(node, h));
}
}
int read_() {
int n, m, parent;
scanf("%d%d", &n, &m);
for (int i = 2; i <= n; i++) {
scanf("%d", &parent);
nodes[parent].push_back(i);
}
Euler.push_back(make_pair(-1, -1));
left_root_right(1, 0);
return m;
}
// Pozitia minimului;
int min_(int p1, int p2) {
return (Euler[p1].second <= Euler[p2].second ? p1 : p2);
}
int get_ancestor(int x, int y) {
int k = (int)(floor(log2(y - x)));
return min_(PMin[x][k], PMin[y - (1 << k) + 1][k]);
}
void compute_rmq() {
int n = Euler.size() - 1;
for (int i = 1; i <= n; i++) {
PMin[i][0] = i;
}
for (int j = 1; j <= LIMIT; j++) {
int Lung_Interv = 1 << j;
for (int i = 1; i + Lung_Interv - 1 <= n; i++) {
PMin[i][j] = min_(PMin[i][j - 1], PMin[i + (1 << (j - 1))][j - 1]);
}
}
}
int minVal(int x, int y) {
return (x < y ? x : y);
}
int maxVal(int x, int y) {
return (x > y ? x : y);
}
void solve_(int m) {
int x, y;
for (int i = 0; i < m; i++) {
scanf("%d%d", &x, &y);
int anc = get_ancestor(minVal(Pos[x], Pos[y]), maxVal(Pos[x], Pos[y]));
printf("%d\n", Euler[anc].first);
}
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int m = read_();
compute_rmq();
solve_(m);
return 0;
}