Pagini recente » Cod sursa (job #2722834) | Cod sursa (job #3295394) | Cod sursa (job #3214817) | Cod sursa (job #3122524) | Cod sursa (job #1605139)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define pair pair<int,int>
const int NMAX = 100000;
const int MMAX = 2000000;
const int H = 18;
int n; int m;
vector<int> g[NMAX + 1];
int euler[NMAX * 2]; int cnt;
int lev[NMAX * 2];
int rmq[H][NMAX * 2]; //rmq[i][j] = min(v[j] ... v[j + (1 << i) - 1]) inclusiv
int lg[NMAX * 2]; //lg[i] cel mai mare nr x ai 2 ^ x <= i
//ficare muchie vine cu 2 noduri, avem 2 * (n - 1) muchii + 1 pentru radacina + 1 indexare de la 1 => n * 2
vector<int> first(NMAX + 1, 0);
void read() {
fin >> n >> m;
for(int i = 2; i <= n; ++i) {
int x; fin >> x;
g[x].push_back(i);
}
}
void dfsEuler(int x, int level) {
euler[++cnt] = x;
lev[cnt] = level;
first[x] = cnt;
for(int node : g[x]) {
dfsEuler(node, level + 1);
euler[++cnt] = x;
lev[cnt] = level;
}
}
void constructRmq() {
for(int i = 1; i <= cnt; ++i)
rmq[0][i] = i;
for(int i = 1; (1 << i) <= cnt; ++i)
for(int j = 1; j + (1 << i) - 1 <= cnt; ++j) {
rmq[i][j] = rmq[i - 1][j];
if(lev[rmq[i][j]] > lev[ rmq[i - 1][j + ( 1 << (i - 1) )] ])
rmq[i][j] = rmq[i - 1][j + ( 1 << (i - 1) )];
}
lg[1] = 0;
for(int i = 2; i <= cnt; ++i)
lg[i] = lg[i/2] + 1;
}
int lca(int x, int y) {
if(first[x] > first[y]) swap(x, y);
int dim = first[y] - first[x] + 1;
int lgDim = lg[dim];
int sol = rmq[lgDim][first[x]];
if(lev[sol] > lev[ rmq[lgDim][ first[y] - (1 << lgDim) + 1] ])
sol = rmq[lgDim][ first[y] - (1 << lgDim) + 1];
return euler[sol];
}
void solve() {
dfsEuler(1, 0);
constructRmq();
while(m--) {
int x; int y;
fin >> x >> y;
fout << lca(x, y) << '\n';
}
}
int main() {
read();
solve();
return 0;
}