Skip to content

Commit

Permalink
Virtual tree update
Browse files Browse the repository at this point in the history
Also some changes to LCA
  • Loading branch information
radoslav11 committed Oct 3, 2024
1 parent cc78b73 commit 1d89ff0
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 6 deletions.
File renamed without changes.
10 changes: 8 additions & 2 deletions tree/lca.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class LCAUtils {
int max_log, dfs_time;
vector<vector<int>> par_up;

void dfs_lca(int u, int pr, int &dfs_time) {
void dfs_lca(int u, int pr, int& dfs_time) {
in_time[u] = ++dfs_time;
par_up[u][0] = pr;
for(int i = 1; i < max_log; i++) {
Expand All @@ -27,7 +27,13 @@ class LCAUtils {
vector<int> in_time, out_time;
vector<vector<int>> adj;

LCAUtils() {}
LCAUtils() : n(0) {}
LCAUtils(int _n) { init(_n); }
LCAUtils(int _n, const vector<vector<int>>& _adj, int root = 0) {
init(_n);
adj = _adj;
prepare(root);
}

void init(int _n) {
n = _n;
Expand Down
15 changes: 11 additions & 4 deletions tree/lca_sparse_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ class LCAUtilsRMQ {
int n;
vector<vector<int>> adj;

LCAUtilsRMQ() { n = 0; }
LCAUtilsRMQ(int _n) { init(_n); }
LCAUtilsRMQ(int _n, const vector<vector<int>>& _adj) {
init(_n);
adj = _adj;
}

void add_edge(int u, int v) {
adj[u].push_back(v);
adj[v].push_back(u);
Expand All @@ -37,13 +44,13 @@ class LCAUtilsRMQ {
void init(int _n) {
n = _n;
order.clear();
adj.assign(n + 1, {});
adj.assign(n, {});
}

void prepare(int root = 1) {
void prepare(int root = 0) {
order.clear();
pos.resize(n + 1);
dep.resize(n + 1);
pos.resize(n);
dep.resize(n);
pre_dfs(root);
rmq.init(order);
}
Expand Down
59 changes: 59 additions & 0 deletions tree/virtual_tree.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <bits/stdc++.h>
#include <coding_library/tree/lca.hpp>
using namespace std;

class VirtualTree : public LCAUtils {
public:
VirtualTree() : LCAUtils() {}
VirtualTree(int n) : LCAUtils(n) {}
VirtualTree(int n, const vector<vector<int>>& adj, int root = 0)
: LCAUtils(n, adj, root) {
prepare(root);
}

void add_edge(int u, int v) { LCAUtils::add_edge(u, v); }

pair<vector<vector<int>>, vector<int>> build(const vector<int>& vertices) {
if(vertices.empty()) {
return {{}, {}};
}

vector<int> vec = vertices;
sort(vec.begin(), vec.end(), [&](int u, int v) {
return in_time[u] < in_time[v];
});
vec.erase(unique(vec.begin(), vec.end()), vec.end());

for(int i = (int)vec.size() - 1; i > 0; i--) {
vec.push_back(lca(vec[i - 1], vec[i]));
}

sort(vec.begin(), vec.end(), [&](int u, int v) {
return in_time[u] < in_time[v];
});
vec.erase(unique(vec.begin(), vec.end()), vec.end());

vector<vector<int>> virtual_adj(vec.size());

stack<int> s;
s.push(0);
for(int i = 1; i < (int)vec.size(); i++) {
while(!upper(vec[s.top()], vec[i])) {
int u = s.top();
s.pop();
int v = s.top();
virtual_adj[v].push_back(u);
}
s.push(i);
}

while(s.size() > 1) {
int u = s.top();
s.pop();
int v = s.top();
virtual_adj[v].push_back(u);
}

return {virtual_adj, vec};
}
};

0 comments on commit 1d89ff0

Please sign in to comment.