Pagini recente » Cod sursa (job #1859715) | Cod sursa (job #1400990) | Cod sursa (job #1485116) | Cod sursa (job #1741013) | Cod sursa (job #3260873)
#include <iostream>
#include <vector>
#define MAX_N 100005
#define MAX_LOGN 20
using namespace std;
int p[MAX_N];
int d[MAX_N];
vector<int> lca;
int first[MAX_N];
int last[MAX_N];
vector<int> v[MAX_N];
// starting from first of size 2 ^ second.
int rmq[MAX_N][MAX_LOGN];
int n, m;
void prepare_lca(int root, int depth)
{
lca.push_back(root);
d[root] = depth;
first[root] = ((int)lca.size()) - 1;
last[root] = ((int)lca.size()) - 1;
for (auto j: v[root]) {
prepare_lca(j, depth + 1);
lca.push_back(root);
last[root] = ((int)lca.size()) - 1;
}
}
// rmq now if I remember properly
int unite_rmq(int a, int b)
{
if (d[a] < d[b])
return a;
return b;
}
void make_rmq_lca()
{
for (int i = 0; i < (int) lca.size(); i++)
rmq[i][0] = lca[i];
for (int j = 1; (1 << j) < (int) lca.size(); j++) {
for (int i = 0; i + (1 << j) - 1 < (int) lca.size(); i++) {
int nxt = i + (1 << (j - 1)) - 1;
rmq[i][j] = unite_rmq(rmq[i][j - 1], rmq[nxt][j - 1]);
}
}
}
int main()
{
FILE * fin = fopen("lca.in", "r");
FILE * fout = fopen("lca.out", "w");
fscanf(fin, "%d %d", &n, &m);
for (int i = 1; i < n; i++) {
fscanf(fin, "%d", &p[i]);
p[i]--;
v[p[i]].push_back(i);
}
prepare_lca(0, 0);
make_rmq_lca();
for (int i = 0; i < m; i++) {
int a, b;
fscanf(fin, "%d %d", &a, &b);
a--; b--;
int pos = min(first[a], first[b]);
int siz = max(last[a], last[b]) - pos + 1;
int pow2 = 0;
int lowest = lca[pos];
while (siz != 0) {
if (((1 << pow2) & siz) != 0)
{
siz -= 1 << pow2;
lowest = unite_rmq(rmq[pos][pow2], lowest);
pos += 1 << pow2;
}
pow2++;
}
fprintf(fout, "%d\n", lowest + 1);
}
}