Pagini recente » Cod sursa (job #2965035) | Cod sursa (job #3135603) | Cod sursa (job #1395007) | Cod sursa (job #2175563) | Cod sursa (job #3330739)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<pair<int, int>>euler;
vector<vector<int>>v;
vector<vector<int>>m;
vector<int>nivel;
vector<int>lg;
vector<int>indice_prima_aparitie;
int n, q;
int x, y, z, k;
void citire_graf()
{
fin >> n >> q;
v.resize(n + 1);
indice_prima_aparitie.resize(n + 1);
nivel.resize(n + 1);
nivel[1] = 0;
for (int i = 2; i <= n; i++)
{
fin >> x;
v[x].push_back(i);
}
}
void dfs_euler(int nod)
{
euler.push_back({ nod, nivel[nod] });
indice_prima_aparitie[nod] = euler.size() - 1;
for (auto i : v[nod])
{
nivel[i] = nivel[nod] + 1;
dfs_euler(i);
euler.push_back({ nod,nivel[nod] });
}
}
void afis_euler()
{
for (auto i : euler)
fout << i.first << " " << i.second << '\n';
fout << '\n' << '\n';
for (int i = 1; i <= n; i++)
fout << indice_prima_aparitie[i] << " ";
}
int main()
{
citire_graf();
euler.push_back({ 0,0 });
dfs_euler(1);
n = (2 * n) - 1;
lg.resize(n + 1);
lg[1] = 0;
for (int i = 2; i <= n; i++)
lg[i] = lg[i / 2] + 1;
m.resize(lg[n] + 1, vector<int>(n + 1));
for (int i = 1; i <= n; i++)
m[0][i] = i;
for(int i=1;(1<<i)<=n;i++)
for (int j = 1; j + (1 << i) <= n + 1; j++)
{
if (euler[m[i - 1][j]].second < euler[m[i - 1][j + (1 << (i - 1))]].second)
m[i][j] = m[i - 1][j];
else
m[i][j] = m[i - 1][j + (1 << (i - 1))];
}
for (int i = 1; i <= q; i++)
{
fin >> x >> y;
x = indice_prima_aparitie[x];
y = indice_prima_aparitie[y];
if (x > y)
swap(x, y);
k = lg[y - x + 1];
if (euler[m[k][x]].second < euler[m[k][y - (1 << k) + 1]].second)
fout << euler[m[k][x]].first;
else
fout << euler[m[k][y - (1 << k) + 1]].first;
fout << '\n';
}
return 0;
}