Pagini recente » Cod sursa (job #1941966) | Cod sursa (job #2370165) | Cod sursa (job #2090761) | Cod sursa (job #1078031) | Cod sursa (job #3235332)
#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
const int NMAX = 100001;
const int LMAX = 30;
vector<int> G[NMAX];
long long k, n, m;
int nivel[2 * NMAX], euler[2 * NMAX], prima_apar[NMAX]; // euler tur- 2*nr muchii
ifstream fin("lca.in");
ofstream fout("lca.out");
int lg[2 * NMAX + 1];
int rmq[2 * NMAX + 1][LMAX];
void createLog()
{
lg[1] = 0;
for (int i = 2; i <= 2 * NMAX; i++)
lg[i] = lg[i / 2] + 1;
}
void preprocRMQ(int a[2 * NMAX], int n)
{
for (int i = 0; i < n; i++)
rmq[i][0] = a[i];
for (int j = 1; (1 << j) <= n; j++)
for (int i = 0; i + (1 << j) - 1 < n; i++)
rmq[i][j] = min(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
}
int query(int x, int y)
{
int k = lg[y - x + 1];
return min(rmq[x][k], rmq[y - (1 << k) + 1][k]);
}
void parcurg(int nod, int niv_curent)
{
k = k + 1;
euler[k] = nod;
nivel[k] = niv_curent;
prima_apar[nod] = k;
for (auto it : G[nod])
{
parcurg(it, niv_curent + 1);
k = k + 1;
euler[k] = nod;
nivel[k] = niv_curent;
}
}
int main()
{
int x;
createLog();
fin >> n >> m;
for (int i = 2; i <= n; i++)
{
fin >> x;
G[x].push_back(i);
}
k = -1;
parcurg(1, 0);
// for (int i = 0; i <= k; i++)
// cout << euler[i] << " ";
// cout << "\n";
// for (int i = 0; i <= k; i++)
// cout << nivel[i] << " ";
// cout << "\n";
// for (int i = 1; i <= n; i++)
// cout << i << " " << prima_apar[i] << endl;
// cout << endl;
preprocRMQ(nivel, k);
for (int i = 0; i < m; i++)
{
int x, y;
fin >> x >> y;
int px = prima_apar[x];
int py = prima_apar[y];
if (px > py)
{
int aux = px;
px = py;
py = aux;
}
int level = query(px, py);
bool found = false;
for (int j = px; j <= py && found == false; j++)
{
if (level == nivel[j])
{
fout << euler[j] << endl;
found = true;
}
}
}
return 0;
}