Pagini recente » Cod sursa (job #309318) | Cod sursa (job #2335211) | Cod sursa (job #587607) | Cod sursa (job #114052) | Cod sursa (job #2093432)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
class Hpd {
public:
Hpd(int n, int m) {
this -> n = n;
this -> m = m;
_chain.resize(n + 1);
_level.resize(n + 1);
_chain_lvl.resize(n + 1);
_tata.resize(n + 1);
_chain_of.resize(n + 1);
_weight.resize(n + 1);
_gr.resize(n + 1);
max_chain = 0;
max_chain_lvl = 0;
for (int i = 2; i <= n; i ++) {
cin >> _tata[i];
_gr[_tata[i]].push_back(i);
}
_Init(1, 1);
_Set_lvl(1, 1);
lim = log2(max_chain_lvl);
_dp.resize(lim + 1);
for (auto &x : _dp) {
x.resize(n + 1);
}
for (int i = 1; i <= n; i ++) {
_dp[0][i] = _tata[_chain[_chain_of[i]].back()];
}
for (int i = 1; i <= lim; i ++) {
for (int j = 1; j <= n; j ++) {
_dp[i][j] = _dp[i - 1][_dp[i - 1][j]];
}
}
}
void Solve() {
int x, y;
for (int i = 1; i <= m; i ++) {
cin >> x >> y;
if (_chain_lvl[x] > _chain_lvl[y]) {
swap(x, y);
}
int dif = _chain_lvl[y] - _chain_lvl[x];
int bit = 0;
while (dif) {
if (dif & 1) {
y = _dp[bit][y];
}
dif >>= 1;
bit += 1;
}
for (int i = lim; i >= 0; i --) {
if (_chain_of[_dp[i][x]] != _chain_of[_dp[i][y]]) {
x = _dp[i][x];
y = _dp[i][y];
}
}
if (_chain_of[x] != _chain_of[y]) {
x = _dp[0][x];
y = _dp[0][y];
}
if (_level[x] >= _level[y]) {
cout << y << '\n';
}
else {
cout << x << '\n';
}
}
}
private:
int n, m, max_chain, lim, max_chain_lvl;
vector < int > _level, _chain_of, _weight, _tata, _chain_lvl;
vector < vector < int > > _chain, _gr, _dp;
void _Init(int cur_node, int cur_level) {
_level[cur_node] = cur_level;
if (_gr[cur_node].size() == 0) {
_chain[++ max_chain].push_back(cur_node);
_chain_of[cur_node] = max_chain;
_weight[max_chain] = 1;
return;
}
int best = -1, max_w = -1;
for (auto x : _gr[cur_node]) {
_Init(x, cur_level + 1);
if (_weight[_chain_of[x]] > max_w) {
best = x;
max_w = _weight[_chain_of[x]];
}
}
_chain[_chain_of[best]].push_back(cur_node);
_chain_of[cur_node] = _chain_of[best];
_weight[_chain_of[best]] += 1;
for (auto x : _gr[cur_node]) {
if (x == best) {
continue;
}
_weight[_chain_of[best]] += _weight[_chain_of[x]];
}
}
void _Set_lvl(int cur_node, int cur_level) {
_chain_lvl[cur_node] = cur_level;
max_chain_lvl = max(max_chain_lvl, cur_level);
for (auto x : _gr[cur_node]) {
if (_chain_of[x] != _chain_of[cur_node]) {
_Set_lvl(x, cur_level + 1);
}
else {
_Set_lvl(x, cur_level);
}
}
}
};
int main() {
int n, m;
cin >> n >> m;
Hpd *H = new Hpd(n, m);
//H -> Solve();
}