Pagini recente » Borderou de evaluare (job #852172) | Borderou de evaluare (job #2493237) | Borderou de evaluare (job #2634876) | Borderou de evaluare (job #2190916) | Cod sursa (job #3148905)
#include <fstream>
#include <vector>
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
static constexpr int NMAX = (int)(1e5 + 1), LOGMAX = 20;
static const int ROOT = 1;
int Log[NMAX];
int N;
vector<int> G[NMAX];
int level[NMAX];
int t[LOGMAX][NMAX];
static inline int read()
{
int q = 0;
f.tie(nullptr);
f >> N >> q;
for (int i = 2; i <= N; ++i)
f >> t[0][i], G[t[0][i]].push_back(i);
return q;
}
static inline void go(const int &node = ROOT, const int &level_node = 0)
{
level[node] = level_node;
for (auto it : G[node])
go(it, (level_node + 1));
return;
}
static inline void precalculation()
{
Log[1] = 0;
for (int i = 2; i <= N; ++i)
Log[i] = 1 + Log[(i >> 1)];
for (int i = 1; i <= Log[N]; ++i)
for (int j = 1; j <= N; ++j)
t[i][j] = t[i - 1][t[i - 1][j]];
return;
}
static inline void my_swap(int &a, int &b)
{
a = (a ^ b), b = (a ^ b), a = (a ^ b);
return;
}
static inline int get_lca(int &x, int &y)
{
if (x == y)
return x;
if (t[0][x] == y)
return y;
if (t[0][y] == x)
return x;
if (level[y] < level[x])
my_swap(x, y);
int diff = level[y] - level[x];
if (diff > 0)
for (int i = Log[diff]; i >= 0; --i)
if (diff & (1 << i))
y = t[i][y];
if (x == y)
return x;
int curr_level = level[x];
for (int i = Log[curr_level]; i >= 0 && x && y; --i)
if (t[i][x] && t[i][y] && t[i][x] != t[i][y])
x = t[i][x], y = t[i][y];
return t[0][x];
}
static inline void test_case()
{
int x = 0, y = 0;
f >> x >> y;
g << get_lca(x, y) << '\n';
return;
}
int main()
{
int q = read();
go();
precalculation();
for (int i = 1; i <= q; ++i)
test_case();
return 0;
}