Pagini recente » Cod sursa (job #804255) | Borderou de evaluare (job #1036606) | Cod sursa (job #2519749) | Cod sursa (job #1665995) | Cod sursa (job #2720481)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
const int NMAX = 100001;
const int LOG = 20;
int n, m, euler[2 * NMAX], level[2 * NMAX], k, logarithm[2 * NMAX], RMQ[LOG][2 * NMAX], lookup[NMAX];
vector < int > G[NMAX];
void eulerTraversal(int node, int l) {
euler[++k] = node;
level[k] = l;
lookup[node] = k; /// pe ce pozitie se afla node in parcurgerea euler
for(auto& it : G[node]) {
eulerTraversal(it, l + 1);
euler[++k] = node;
level[k] = l; /////// BE CAREFUL HERE.
}
}
int main() {
f >> n >> m;
for (int i = 2; i <= n; ++i) {
int x;
f >> x;
G[x].push_back(i);
}
eulerTraversal(1, 1);
for (int i = 2; i <= k; ++i)
logarithm[i] = 1 + logarithm[i / 2];
/// fac RMQ
for (int i = 1; i <= k; ++i)
RMQ[0][i] = i;
for (int i = 1; i <= logarithm[k] + 1; ++i){
for (int j = 1; j <= k; ++j) {
RMQ[i][j] = RMQ[i - 1][j];
if(j + (1 << (i - 1)) <= k &&
level[ RMQ[i - 1][j] ] > level[ RMQ[i - 1][j + (1 << (i - 1) ) ] ]) {
RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
}
}
}
for(;m--;) {
int x, y;
f >> x >> y;
x = lookup[x];
y = lookup[y];
if(x > y)
swap(x, y);
int logg = logarithm[y - x + 1];
if(level[ RMQ[logg][x] ] < level[ RMQ[logg][ y - (1 << logg) + 1 ] ])
g << euler[ RMQ[logg][x] ] << '\n';
else
g << euler[ RMQ[logg][ y - (1 << logg) + 1 ] ] << '\n';
}
return 0;
}