Pagini recente » Cod sursa (job #1006727) | Cod sursa (job #360827) | Cod sursa (job #1191253) | Cod sursa (job #68531) | Cod sursa (job #1462328)
#include <iostream>
#include <fstream>
#include <assert.h>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
const char IN[] = "lca.in", OUT[] = "lca.out";
const int NMAX = 100001;
const int LOGNMAX = 17;
using namespace std;
int N, M;
int PI[NMAX];
list<int> T[NMAX];
int euler[NMAX * 2];
int depth[NMAX];
int pos[NMAX];
int discovery_time;
int RMQ[NMAX][LOGNMAX];
inline void euler_search(int node, int dpth)
{
euler[++discovery_time] = node;
depth[node] = dpth;
pos[node] = discovery_time;
for (auto &ch : T[node]) {
euler_search(ch, dpth+1);
euler[++discovery_time] = node;
}
}
inline void preprocess()
{
for (int i = 1; i <= discovery_time; ++i)
RMQ[i][0] = i;
for (int j = 1; (1 << j) <= discovery_time; ++j) {
for (int i = 1; i + (1 << j) - 1 <= discovery_time; ++i) {
if (depth[euler[RMQ[i][j - 1]]] <
depth[euler[RMQ[i + (1 << (j - 1))][j - 1]]])
RMQ[i][j] = RMQ[i][j - 1];
else RMQ[i][j] = RMQ[i + (1 << (j - 1))][j - 1];
}
}
}
inline void read_data()
{
assert(freopen(IN, "r", stdin));
assert(freopen(OUT, "w", stdout));
assert(scanf("%d %d", &N, &M));
for (int i = 2; i <= N; ++i) {
assert(scanf("%d", &PI[i]));
T[PI[i]].push_back(i);
}
euler_search(1, 1);
preprocess();
for (int i = 1; i <= M; ++i) {
int u, v;
assert(scanf("%d %d", &u, &v));
u = pos[u];
v = pos[v];
if (u > v) std::swap(u, v);
int divide = (int)log2(v - u + 1);
int lowest_ancestor = euler[RMQ[u][divide]];
if (depth[euler[RMQ[u][divide]]] > depth[euler[RMQ[v - (1 << divide) + 1][divide]]])
lowest_ancestor = euler[RMQ[v - (1 << divide) + 1][divide]];
printf("%d\n", lowest_ancestor);
}
fclose(stdin);
fclose(stdout);
}
int main()
{
read_data();
return 0;
}