Pagini recente » Cod sursa (job #3242442) | Cod sursa (job #1754654) | Cod sursa (job #2933204) | Cod sursa (job #827292) | Cod sursa (job #3211262)
#include <fstream>
#include <vector>
#define NMAX 100005
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, m;
int x;
vector<int> l[NMAX];
vector<pair<int, int>> euler;
bool f[NMAX];
int dp[NMAX*2][30];
int a, b;
int log[NMAX*2];
int first[NMAX];
int i, j;
void dfs(int, int);
int lca(int, int);
int main()
{
log[1] = 0;
for (i = 2; i < 2*NMAX; ++i)
log[i] = log[i/2] + 1;
fin >>n>>m;
for (i = 2; i <= n; ++i)
{
fin >>x;
l[x].push_back(i);
l[i].push_back(x);
}
dfs(1, 0);
for (i = 0; i < euler.size(); ++i)
dp[i][0] = i;
for (j = 1; (1<<j) <= euler.size(); ++j)
for (i = 0; i+(1<<j)-1 < euler.size(); ++i)
{
a = dp[i][j-1];
b = dp[i+(1<<(j-1))][j-1];
dp[i][j] = (euler[a].second < euler[b].second? a: b);
}
for (i = 1; i <= m; ++i)
{
fin >>a>>b;
fout <<lca(a, b)<<'\n';
}
fout.close();
return 0;
}
int lca(int l, int r)
{
l = first[l]; r = first[r];
if (l > r) swap(l, r);
int lg = log[r-l+1];
int x = dp[l][lg];
int y = dp[r-(1<<lg)+1][lg];
return (euler[x].second < euler[y].second? euler[x].first: euler[y].first);
}
void dfs(int vf, int niv)
{
f[vf] = 1;
first[vf] = euler.size();
euler.push_back({vf, niv});
for (auto vfnou: l[vf])
if (!f[vfnou])
{
dfs(vfnou, niv+1);
euler.push_back({vf, niv});
}
}