Pagini recente » Cod sursa (job #2103596) | Cod sursa (job #1683434) | Cod sursa (job #2286072) | Cod sursa (job #3282348) | Cod sursa (job #2930816)
#include <fstream>
#include <vector>
#include <bitset>
#include <math.h>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
const int N = 2e5 + 1;
int l[N + 1], h[N + 1], euler[N + 1], prim[N + 1], lg[N + 1];
pair <int, int> 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];
int val1 = r[e][dr].first;
int val2 = r[e][st + (1 << e) - 1].first;
if (val1 < val2)cout << r[e][dr].second << '\n';
else cout << r[e][st + (1 << e) - 1].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)
{
int val1 = r[i - 1][j].first;
int val2 = r[i - 1][j - (1 << (i - 1))].first;
if (val1 <= val2)
r[i][j] = {val1, r[i - 1][j].second};
else
r[i][j] = {val2, r[i - 1][j - (1 << (i - 1))].second};
}
while (q-- && cin >> x >> y)
lcaquery(x, y);
return 0;
}