Pagini recente » Cod sursa (job #2605529) | Cod sursa (job #2899032) | Cod sursa (job #1204680) | Cod sursa (job #1140084) | Cod sursa (job #1905249)
#include <stdio.h>
struct node {
int v;
node *n;
};
node* all() {
static int sp = 1000;
static node* st = NULL;
if (sp == 1000) {
sp = 0;
st = new node[1000];
}
return st + (sp++);
}
namespace Var {
FILE *fin, *fout;
int N, M;
node **G;
int e, *euler;
int *lvl, *fi;
int *lg, **m;
};
void citire() {
using namespace Var;
fscanf(fin, "%d%d", &N, &M);
G = new node*[N + 1]();
for (int i = 2; i <= N; ++i) {
int x;
fscanf(fin, "%d", &x);
node *edge = all();
edge->v = i;
edge->n = G[x];
G[x] = edge;
}
euler = new int[2*N - 1];
lvl = new int[N + 1];
fi = new int[N + 1];
}
void f_euler(int u = 1, int dep = 0) {
using namespace Var;
lvl[u] = dep;
fi[u] = e;
euler[e++] = u;
for (node* it = G[u]; it; it = it->n) {
f_euler(it->v, dep + 1);
euler[e++] = u;
}
}
int mi(int x, int y) {
using namespace Var;
return (lvl[euler[x]] < lvl[euler[y]] ? x : y);
}
void pre_rmq() {
using namespace Var;
// Fac vectorul lg
lg = new int[e + 1];
lg[1] = 0;
for (int i = 2; i <= e; ++i) {
lg[i] = 1 + lg[i / 2];
}
// Fac tabloul m
m = new int*[lg[e] + 1];
for (int i = 0; i <= lg[e]; ++i) {
m[i] = new int[e];
}
for (int i = 0; i <= e; ++i) {
m[0][i] = i;
}
for (int i = 1; i <= lg[e]; ++i) {
for (int j = 0; j < e; ++j) {
if (j + (1 << (i-1)) < e) {
m[i][j] = mi(m[i-1][j], m[i-1][j + (1<<(i-1))]);
} else {
m[i][j] = m[i-1][j];
}
}
}
}
int rmq(int l, int r) {
using namespace Var;
return mi(m[lg[r - l + 1]][l], m[lg[r - l + 1]][r - (1 << lg[r-l+1]) + 1]);
}
int lca(int x, int y) {
using namespace Var;
if (fi[x] < fi[y]) {
return euler[rmq(fi[x], fi[y])];
} else {
return euler[rmq(fi[y], fi[x])];
}
}
void afisare() {
using namespace Var;
for (int i = 0; i < M; ++i) {
int x, y;
fscanf(fin, "%d%d", &x, &y);
fprintf(fout, "%d\n", lca(x, y));
}
}
int main()
{
using namespace Var;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
citire();
f_euler();
pre_rmq();
afisare();
fclose(fin);
fclose(fout);
return 0;
}