Pagini recente » Istoria paginii utilizator/nizisti | Cod sursa (job #2098529) | Cod sursa (job #2466566) | Cod sursa (job #1634552) | Cod sursa (job #2989512)
#include <fstream>
#include <vector>
#define NMAX 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int x, y;
vector<int> l[NMAX];
vector<pair<int, int>> euler; int first[NMAX];
bool f[NMAX];
int rmq[NMAX][30];
int logaritm[2*NMAX];
int i, j;
void dfs(int, int);
void calcrmq();
int lca(int, int);
int main()
{
logaritm[2] = 1;
for (i = 3; i < 2*NMAX; ++i)
logaritm[i] = logaritm[i/2] + 1;
fin >>n>>m;
for (i = 2; i <= n; ++i)
{
fin >>x;
l[i].push_back(x);
l[x].push_back(i);
}
dfs(1, 0);
calcrmq();
for (i = 1; i <= m; ++i)
{
fin >>x>>y;
fout <<lca(x, y)<<'\n';
}
fout.close();
return 0;
}
int lca(int x, int y)
{
x = first[x]; y = first[y];
if (x > y) swap(x, y);
int lg = logaritm[y-x+1];
int l = rmq[x][lg];
int r = rmq[y-(1<<lg)+1][lg];
return (euler[l].second < euler[r].second)? euler[l].first: euler[r].first;
}
void calcrmq()
{
int n = euler.size();
int l, r;
int i, j;
for (i = 0; i < n; ++i)
rmq[i][0] = i;
for (j = 1; (1<<j) <= n; ++j)
for (i = 0; i+(1<<j)-1 < n; ++i)
{
l = rmq[i][j-1];
r = rmq[i+(1<<(j-1))][j-1];
rmq[i][j] = (euler[l].second < euler[r].second)? l: r;
}
}
void dfs(int vf, int lvl)
{
f[vf] = 1;
first[vf] = euler.size();
euler.push_back({vf, lvl});
for (auto vfnou: l[vf])
if (!f[vfnou])
{
dfs(vfnou, lvl+1);
euler.push_back({vf, lvl});
}
}