Pagini recente » Cod sursa (job #2243686) | Cod sursa (job #2670113) | Cod sursa (job #150361) | Cod sursa (job #1559608) | Cod sursa (job #2939677)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int nmax = 1e5, logmax = 18;
int n, m, euler_index, logs[nmax * 2], pos[nmax + 1], level[nmax * 2] , euler[nmax * 2], rmq[nmax * 2][logmax + 1];
vector<int> edges[nmax + 1];
void dfs(int nod, int curr_level) {
pos[nod] = ++euler_index;
euler[euler_index] = nod, level[euler_index] = curr_level;
for (auto child : edges[nod])
if (!pos[child]) {
dfs(child, curr_level + 1);
euler[++euler_index] = nod, level[euler_index] = curr_level;
}
}
int query(int x, int y) {
int len = logs[y - x + 1];
if (level[rmq[x][len]] <= level[rmq[y - (1 << len) + 1][len]])
return rmq[x][len];
return rmq[y - (1 << len) + 1][len];
}
int main() {
cin >> n >> m;
logs[0] = -1;
for (int i = 1; i < nmax * 2; i++)
logs[i] = logs[i / 2] + 1;
for (int i = 1; i < n; i++) {
int t;
cin >> t;
edges[t].push_back(i + 1), edges[i + 1].push_back(t);
}
dfs(1, 0);
for (int i = 1; i < 2 * n; i++)
rmq[i][0] = i;
for (int j = 1; (1 << j) < 2 * n; j++) {
for (int i = 1; i + (1 << j) - 1 < 2 * n; i++) {
if (level[rmq[i][j - 1]] <= level[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];
}
}
for (int i = 1; i <= m; i++) {
int x, y;
cin >> x >> y;
if (pos[x] > pos[y])
swap(x, y);
cout << euler[query(pos[x], pos[y])] << "\n";
}
}