Pagini recente » Autentificare | Istoria paginii runda/oni_mixt2/clasament | Monitorul de evaluare | fmi-no-stress-9/solutii | Cod sursa (job #1689997)
#include <fstream>
#include <vector>
using namespace std;
int nivel[100010], tata[100010], r[100010][19];
ifstream in("lca.in");
vector <int> adia[100010], euler;
int n, m;
void parc_euler(int nod);
void cit();
int prima_aparitie[100010];
int log[300010];
int main()
{
cit();
ofstream out("lca.out");
int a, b;
while (m--) {
in >> a >> b;
a = prima_aparitie[a];
b = prima_aparitie[b];
if (a > b) {
int d = a;
a = b;
b = d;
}
int l = log[(b - a + 1)];
if (nivel[r[b][l]] < nivel[r[a + (1 << l)][l]])
out << r[b][l] << '\n';
else
out << r[a + (1 << l)][l] << '\n';
}
return 0;
}
void cit() {
in >> n >> m;
for (int i = 2; i <= n; i++) {
in >> tata[i];
adia[tata[i]].push_back(i);
}
parc_euler(1);
int s = euler.size();
for (int i = 0; i < s; i++) {
r[i][0] = euler[i];
}
for (int i = 1; i < 19; i++) {
for (int j = 0; j < s; j++) {
r[j][i] = r[j][i - 1];
if (( j - (1 << (i - 1)) >= 0) && nivel[r[j - (1 << (i - 1))][i - 1]] < nivel[r[j][i]]) {
r[j][i] = r[j - (1 << (i - 1))][i - 1];
}
}
}
for (int i = 2; i <= n; i++) {
log[i] = 1 + log[i / 2];
}
}
void parc_euler(int nod) {
prima_aparitie[nod] = euler.size();
nivel[nod] = 1 + nivel[tata[nod]];
euler.push_back(nod);
for (auto i : adia[nod]) {
parc_euler(i);
euler.push_back(nod);
}
}