Pagini recente » Cod sursa (job #347140) | Cod sursa (job #1497615) | Cod sursa (job #638497) | Cod sursa (job #1002613) | Cod sursa (job #2645930)
#include <bits/stdc++.h>
using namespace std;
int N, M;
vector<vector<int>> tree;
class RMQ
{
int N, K;
vector<vector<int>> rmq;
public:
RMQ(vector<int>& data)
{
N = data.size() - 1;
K = log2(N);
rmq.resize(K + 1, vector<int>(N + 1));
for(int i = 1; i <= N; ++i)
rmq[0][i] = data[i];
for(int k = 1; k <= K; ++k)
for(int i = 1; i <= N; ++i)
rmq[k][i] = min(rmq[k - 1][i], rmq[k - 1][i + (1 << (k - 1))]);
}
int query(int left, int right)
{
if(left > right) swap(left, right);
int k = log2(right - left + 1);
return min(rmq[k][left], rmq[k][right - (1 << k) + 1]);
}
};
vector<int> flat_tree;
vector<int> old_id;
vector<int> first;
int timer = 0;
void tree_flattering(int node, int parent)
{
int new_id = ++timer;
old_id[new_id] = node;
flat_tree.push_back(new_id);
first[node] = flat_tree.size() - 1;
for(int child : tree[node])
{
if(child == parent) continue;
tree_flattering(child, node);
flat_tree.push_back(new_id);
}
}
int main()
{
ifstream fin{"lca.in"};
ofstream fout{"lca.out"};
fin >> N >> M;
tree.resize(N + 1, vector<int>());
old_id.resize(N + 1);
first.resize(N + 1);
flat_tree.push_back(-1);
for(int node = 2; node <= N; ++node)
{
int parent;
fin >> parent;
tree[parent].push_back(node);
tree[node].push_back(parent);
}
tree_flattering(1, -1);
RMQ rmq(flat_tree);
for(int i = 1; i <= M; ++i)
{
int x, y;
fin >> x >> y;
fout << old_id[rmq.query(first[x], first[y])] << '\n';
}
}