Pagini recente » Cod sursa (job #936174) | Cod sursa (job #1233703) | Cod sursa (job #2494074) | Cod sursa (job #2097626) | Cod sursa (job #2877191)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
//Solutie cu Rmq;
#define DIM 100000
#define MAXLG 20
#define INF (1LL << 30)
int n, m, k;
int ap[DIM + 1];
int Euler[2 * DIM + 1]; //liniarizarea arborelui;
int nivel[2 * DIM + 1];
int lg[2 * DIM + 1]; //logaritm din fiecare numar;
int Rmq[MAXLG + 1][DIM * 8 + 1];
vector <int> G[DIM + 1];
static inline void dfs(int nod, int lvl) {
Euler[++k] = nod;
nivel[k] = lvl;
ap[nod] = k;
for(auto e : G[nod]) {
dfs(e, lvl + 1);
Euler[++k] = nod;
nivel[k] = lvl;
}
}
static inline void RMQ() {
for(int i = 2; i <= k; i++)
lg[i] = lg[i / 2] + 1;
for(int i = 1; i <= k; i++)
Rmq[0][i] = i; //retin indicii;
for(int i = 1; (1 << i) < k; i++)
for(int j = 1; j <= k - (1 << i); j++) {
int l = 1LL << (i - 1); //lungimea intervalului;
if(nivel[Rmq[i - 1][j]] < nivel[Rmq[i - 1][j + l]])
Rmq[i][j] = Rmq[i - 1][j];
else Rmq[i][j] = Rmq[i - 1][j + l];
}
}
static inline int lca(int x, int y) {
int a = ap[x], b = ap[y];
if(a > b)
swap(a, b);
int dif = b - a + 1;
int l = lg[dif];
int q = dif - (1 << l);
int nod;
if(nivel[Rmq[l][a + q]] < nivel[Rmq[l][a]])
nod = Rmq[l][a + q];
else nod = Rmq[l][a];
return Euler[nod];
}
int main() {
fin.tie(0);
fout.tie(0);
fin >> n >> m;
for(int i = 2; i <= n; i++) {
int x;
fin >> x;
G[x].push_back(i);
}
k = 0;
dfs(1, 0);
RMQ();
int x, y;
for(int i = 1; i <= m; i++) {
fin >> x >> y;
fout << lca(x, y) << '\n';
}
return 0;
}