Pagini recente » Cod sursa (job #2598089) | Cod sursa (job #2626826) | Cod sursa (job #2184459) | Cod sursa (job #2291478) | Cod sursa (job #2567136)
#include <bits/stdc++.h>
#define MAXN 100005
#define LOG2 20
int N, M;
std::vector <int> ADC[MAXN];
inline void addEdge(int u, int v) {
ADC[u].push_back(v);
ADC[v].push_back(u);
}
int depth[MAXN], first[MAXN];
int RMQ[LOG2][2*MAXN], logtable[2*MAXN];
std::vector <int> euler;
void DFS(int vertex = 1, int parent = 0) {
first[vertex] = euler.size();
depth[vertex] = depth[parent]+1;
euler.push_back(vertex);
for (auto &it:ADC[vertex]) {
if (it == parent) continue;
DFS(it, vertex);
euler.push_back(vertex);
}
}
void computeRMQ() {
for (int i=2; i<2*MAXN; ++i)
logtable[i] = logtable[i/2] + 1;
for (int i=0; i<euler.size(); ++i)
RMQ[0][i] = euler[i];
for (int i=1; i<LOG2; ++i)
for (int j=0, k=(1<<i); k<euler.size(); ++j, ++k)
RMQ[i][j] = (depth[RMQ[i-1][j]] < depth[RMQ[i-1][j + (1<<(i-1))]] ? RMQ[i-1][j] : RMQ[i-1][j + (1<<(i-1))]);
}
int LCA(int u, int v) {
if (u == v) return u;
int x = first[u];
int y = first[v];
if (x > y) std::swap(x, y);
int len = logtable[y-x+1];
int c1 = RMQ[len][x];
int c2 = RMQ[len][y-(1<<len)+1];
if (depth[c1] < depth[c2]) return c1;
return c2;
}
#define FILENAME std::string("lca")
std::ifstream input (FILENAME+".in");
std::ofstream output(FILENAME+".out");
int32_t main()
{
input >> N >> M;
for (int i=1, u; i<N; ++i)
input >> u, addEdge(u, i+1);
DFS();
computeRMQ();
for (int i=1, x, y; i<=M; ++i)
input >> x >> y, output << LCA(x, y) << '\n';
return 0;
}