Pagini recente » Cod sursa (job #168754) | Cod sursa (job #3122351) | Cod sursa (job #1012297) | Cod sursa (job #1677909) | Cod sursa (job #2029286)
#include <cstdio>
#include <map>
using std::map;
const int MAX_N = 100000;
const int LOG = 18;
int N, M;
int d[MAX_N + 1];
int father[LOG + 1][MAX_N + 1];
map <int, int> lg;
void init() {
int i;
for (i = 0; i <= LOG; i++) {
lg[1 << i] = i;
}
}
int dfs(int u) {
if (d[u] == 0) {
d[u] = dfs(father[0][u]) + 1;
}
}
void climb(int &u, int level) {
while (level) {
u = father[lg[level & -level]][u];
level &= level - 1;
}
}
int lca(int u, int v) {
if (d[u] > d[v]) {
climb(u, d[u] - d[v]);
} else {
climb(v, d[v] - d[u]);
}
if (u == v) {
return u;
}
int i;
for (i = LOG; i >= 0; i--) {
if (father[i][u] != father[i][v]) {
u = father[i][u];
v = father[i][v];
}
}
return father[0][u];
}
int main(void) {
int i, u, v;
FILE *f = fopen("lca.in", "r");
init();
fscanf(f, "%d %d", &N, &M);
for (i = 2; i <= N; i++) {
fscanf(f, "%d", &father[0][i]);
}
d[1] = 1;
for (i = 2; i <= N; i++) {
dfs(i);
}
for (i = 1; i <= LOG; i++) {
for (u = 1; u <= N; u++) {
father[i][u] = father[i - 1][father[i - 1][u]];
}
}
freopen("lca.out", "w", stdout);
while (M) {
fscanf(f, "%d %d", &u, &v);
fprintf(stdout, "%d\n", lca(u, v));
M--;
}
fclose(f);
fclose(stdout);
return 0;
}