Pagini recente » Cod sursa (job #91243) | Cod sursa (job #1056784) | Cod sursa (job #1717080) | Cod sursa (job #1884239) | Cod sursa (job #1653145)
/*#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
vector <int> G[100005];
int n, q, ancestor[20][100005], depth[100005], log_n;
bool used[100005];
void dfs(int node, int step) {
used[node] = true;
for(auto nxt: G[node]) {
if(used[nxt]) {
continue;
}
dfs(nxt, step + 1);
depth[nxt] = step;
}
}
inline void ancestor_init() {
log_n = log2(n) + 1;
for(int i = 1; i <= log_n; ++i) {
for(int j = 1; j <= n; ++j) {
ancestor[i][j] = ancestor[i - 1][ancestor[i - 1][j]];
}
}
}
inline void equalise(int &node_deep, int &node_norm) {
if(depth[node_deep] < depth[node_norm]) {
swap(node_deep, node_norm);
}
int dist = depth[node_deep] - depth[node_norm];
for(int j = 0; j <= log_n; ++j) {
int bitmask = (1 << j);
if(dist & bitmask) {
node_deep = ancestor[j][node_deep];
}
}
}
inline int lca(int node1, int node2) {
if(node1 == node2) {
return node1;
}
for(int j = log_n; j >= 0; --j) {
if(ancestor[j][node1] != ancestor[j][node2] and ancestor[j][node1]) {
node1 = ancestor[j][node1];
node2 = ancestor[j][node2];
}
}
return ancestor[0][node1];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &n, &q);
ancestor[0][1] = 1;
for(int i = 2; i <= n; ++i) {
scanf("%d", &ancestor[0][i]);
G[ancestor[0][i]].push_back(i);
}
dfs(1, 0);
ancestor_init();
for(int i = 1; i <= q; ++i) {
int node1, node2;
scanf("%d%d", &node1, &node2);
equalise(node1, node2);
printf("%d\n", lca(node1, node2));
}
return 0;
}*/
#include <fstream>
#include <cmath>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector <int> G[100005], euler, lvl;
int pos[100005], n, q, rmq[20][100005];
bool used[100005];
void euler_init(int node, int level) {
used[node] = true;
euler.push_back(node);
lvl.push_back(level);
pos[node] = euler.size() - 1;
for(auto it: G[node]) {
if(used[it]) {
continue;
}
euler_init(it, level + 1);
euler.push_back(node);
lvl.push_back(level);
}
}
void rmq_init() {
for(int i = 1; i <= (int) lvl.size(); ++i) {
rmq[0][i] = i;
}
for(int i = 1; (1 << i) <= (int) lvl.size(); ++i) {
for(int j = 1; j + (1 << i) <= (int) lvl.size(); ++j) {
//rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
if(lvl[rmq[i - 1][j] - 1] <= lvl[rmq[i - 1][j + (1 << (i - 1))] - 1]) {
rmq[i][j] = rmq[i - 1][j];
}
else {
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
}
int query(int lft, int rgt) {
int line, skip, rmq_ans;
skip = rgt - lft + 1;
line = log2(skip);
if(lvl[rmq[line][lft] - 1] <= lvl[rmq[line][lft + skip - (1 << line)] - 1]) {
rmq_ans = rmq[line][lft];
}
else {
rmq_ans = rmq[line][lft + skip - (1 << line)];
}
return euler[rmq_ans - 1];
}
int main() {
cin >> n >> q;
for(int i = 2; i <= n; ++i) {
int x;
cin >> x;
G[x].push_back(i);
G[i].push_back(x);
}
euler_init(1, 0);
rmq_init();
/*for(int i = 0; i <= log2(lvl.size()); ++i) {
for(int j = 1; j <= lvl.size(); ++j) {
cout << rmq[i][j] << ' ';
}
cout << '\n';
}*/
for(int i = 1; i <= q; ++i) {
int node1, node2;
cin >> node1 >> node2;
if(pos[node1] > pos[node2]) {
swap(node1, node2);
}
cout << query(pos[node1] + 1, pos[node2] + 1) << '\n';
///+1 because of lvl and euler start from 0 and so does pos, but rmq starts from 1
}
return 0;
}