Pagini recente » Cod sursa (job #3306102) | Cod sursa (job #3306103) | Cod sursa (job #3306101) | Cod sursa (job #3306100) | Cod sursa (job #3306293)
#include <fstream>
#include <set>
#include <queue>
#include <iostream>
using namespace::std;
int n, m;
int visited[100005];
vector<int> eulerTour;
vector<int> eulerTourLevels;
vector<int> firstOccInEuler;
vector<int> lg;
vector<int> edges[100005];
int rmq[32][200005];
void dfs(int node, int level) {
firstOccInEuler[node] = eulerTour.size();
for (int &child: edges[node]) {
eulerTour.push_back(node);
eulerTourLevels.push_back(level);
dfs(child, level + 1);
}
eulerTour.push_back(node);
eulerTourLevels.push_back(level);
}
int lca(int p, int q) {
int firstP = firstOccInEuler[p];
int firstQ = firstOccInEuler[q];
if (firstQ < firstP) swap(firstP, firstQ);
int diff = firstQ - firstP + 1;
int diffLog = lg[diff];
int ans = rmq[diffLog][firstP];
if(eulerTourLevels[ans] > eulerTourLevels[rmq[diffLog][firstQ - (1 << diffLog) + 1]]) ans = rmq[diffLog][firstQ - (1 << diffLog) + 1];
return eulerTour[ans];
}
int main() {
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> parent;
parent.push_back(0);
parent.push_back(0);
fin >> n >> m;
firstOccInEuler.resize(n + 1);
for(int i = 2; i <= n; i++) {
int x;
fin >> x;
parent.push_back(x);
edges[x].push_back(i);
}
// construct euler tour and levels
dfs(1, 0);
// for(int &node: eulerTour) cout << node << ' ';
// cout << '\n';
// build sparse table
for(int j = 0; j < eulerTour.size(); j ++) rmq[0][j] = j;
for(int i = 1; (1 << i) <= eulerTour.size(); i ++) {
for (int j = 0; j + (1 << i) < eulerTour.size(); j ++) {
rmq[i][j] = rmq[i-1][j];
if (eulerTourLevels[rmq[i-1][j + (1 << (i-1))]] < eulerTourLevels[rmq[i][j]])
rmq[i][j] = rmq[i-1][j + (1 << (i-1))];
// cout << i << ' ' << j << ' ' << rmq[i][j] << '\n';
}
}
// // construct logarithms
lg.resize(eulerTour.size());
lg[1] = 0;
for(int i = 2; i < eulerTour.size(); i++) lg[i] = lg [i / 2] + 1;
// answer rmq queries
while (m--) {
int p, q;
fin >> p >> q;
fout << lca(p, q) << '\n';
}
}