This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "tree/xor_tree.hpp"XOR Tree is a space-efficient tree representation using XOR linked lists. It allows traversing a tree from leaves to root without storing parent pointers explicitly.
XorTree(int n)
n verticesvoid add_edge(int u, int v)
u and v
void set_root(int v)
v as the root of the treetemplate<class F1, class F2> void run(F1 &&apply_edge, F2 &&apply_vertex)
apply_edge(p, v) is called for each edge (p, v) where v is a leafapply_vertex(v) is called for each vertex v in order from leaves to
rootauto dfs_ord()
(ord, sz) where:
ord is the DFS order arraysz[v] is the subtree size of vertex v
#pragma once
// clang-format off
struct XorTree {
XorTree() {}
XorTree(int _n) : n(_n), par(n), deg(n) {}
void add_edge(int u, int v) {
par[u] ^= v, par[v] ^= u, deg[u]++, deg[v]++;
}
void set_root(int v) { root = v, deg[v] = -1; }
template<class F1, class F2> void run(F1 &&apply_edge, F2 &&apply_vertex) {
assert(root != -1 && "no root set");
for (int i = 0; i < n; i++) {
int v = i;
for (int p; deg[v] == 1; v = p) {
p = par[v];
deg[v]--, deg[p]--, par[p] ^= v;
apply_vertex(v), apply_edge(p, v);
}
}
apply_vertex(root), par[root] = -1;
}
auto dfs_ord() {
int id = n;
vector<int> sz(n, 1), ord(n);
run(
[&](int v, int c) { sz[v] += sz[c]; },
[&](int v) { ord[--id] = v; }
);
for (int i = 1; i < n; i++) {
int v = ord[i], p = par[v];
tie(sz[v], sz[p]) = make_pair(sz[p], sz[p] - sz[v]);
}
for (int i = 0; i < n; i++) ord[--sz[i]] = i;
return make_pair(ord, sz);
}
private: int n, root = -1;
public: vector<int> par;
private: vector<int> deg;
};
// clang-format on
#line 2 "tree/xor_tree.hpp"
// clang-format off
struct XorTree {
XorTree() {}
XorTree(int _n) : n(_n), par(n), deg(n) {}
void add_edge(int u, int v) {
par[u] ^= v, par[v] ^= u, deg[u]++, deg[v]++;
}
void set_root(int v) { root = v, deg[v] = -1; }
template<class F1, class F2> void run(F1 &&apply_edge, F2 &&apply_vertex) {
assert(root != -1 && "no root set");
for (int i = 0; i < n; i++) {
int v = i;
for (int p; deg[v] == 1; v = p) {
p = par[v];
deg[v]--, deg[p]--, par[p] ^= v;
apply_vertex(v), apply_edge(p, v);
}
}
apply_vertex(root), par[root] = -1;
}
auto dfs_ord() {
int id = n;
vector<int> sz(n, 1), ord(n);
run(
[&](int v, int c) { sz[v] += sz[c]; },
[&](int v) { ord[--id] = v; }
);
for (int i = 1; i < n; i++) {
int v = ord[i], p = par[v];
tie(sz[v], sz[p]) = make_pair(sz[p], sz[p] - sz[v]);
}
for (int i = 0; i < n; i++) ord[--sz[i]] = i;
return make_pair(ord, sz);
}
private: int n, root = -1;
public: vector<int> par;
private: vector<int> deg;
};
// clang-format on