Pagini recente » Cod sursa (job #2348724) | Borderou de evaluare (job #311036) | Cod sursa (job #2669631) | Cod sursa (job #446348) | Cod sursa (job #2930817)
#include <fstream>
#include <vector>
#include <bitset>
#include <math.h>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
using bleat = pair <int, int>;
const int N = 2e5 + 1;
int l[N + 1], h[N + 1], euler[N + 1], prim[N + 1], lg[N + 1];
bleat r[19][N + 1];
vector <int> g[N + 1];
bitset <N + 1> viz;
int n, q, x, y, k;
void dfs (int node)
{
viz[node] = 1;
euler[++k] = node;
for (auto it : g[node])
if (!viz[it])l[it] = l[node] + 1, dfs(it), euler[++k] = node;
}
void lcaquery (int x, int y)
{
int st = min (prim[x], prim[y]), dr = max (prim[x], prim[y]);
int e = lg[dr - st + 1];
bleat val1 = r[e][dr];
bleat val2 = r[e][st + (1 << e) - 1];
if (val1.first < val2.first)cout << val1.second << '\n';
else cout << val2.second << '\n';
}
int main()
{
cin >> n >> q;
for (int i = 1; i < n && cin >> x; ++i)
g[x].push_back(i + 1);
dfs (1);
for (int i = 2; i <= k; ++i)
lg[i] = 1 + lg[i >> 1];
for (int i = 1; i <= k; ++i)
{
h[i] = l[euler[i]];
r[0][i] = {h[i], euler[i]};
if (!prim[euler[i]])prim[euler[i]] = i;
}
for (int i = 1; i <= lg[k]; ++i)
for (int j = 1; j <= k; ++j)
{
bleat val1 = r[i - 1][j];
bleat val2 = r[i - 1][j - (1 << (i - 1))];
r[i][j] = (val1.first < val2.first) ? val1 : val2;
}
while (q-- && cin >> x >> y)
lcaquery(x, y);
return 0;
}