Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 46 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,51 @@ My implementations of various data structures and algorithms for competitive pro
- [0-common](https://github.com/manoflearning/cp-reference-codes/tree/main/src/0-common)
- [`common.hpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/0-common/common.hpp)
- [1-ds](https://github.com/manoflearning/cp-reference-codes/tree/main/src/1-ds)
- [`erasable_pq.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/erasable_pq.cpp)
- [`fenwick_tree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/fenwick_tree.cpp)
- [`li_chao_tree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/li_chao_tree.cpp)
- [`merge_sort_tree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/merge_sort_tree.cpp)
- [`pbds.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/pbds.cpp)
- [`segment_tree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/segment_tree.cpp)
- [`union_find.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/union_find.cpp)
- [`ds_dsu.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_dsu.cpp)
- [`ds_erasable_pq.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_erasable_pq.cpp)
- [`ds_fenwick.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_fenwick.cpp)
- [`ds_li_chao.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_li_chao.cpp)
- [`ds_merge_seg.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_merge_seg.cpp)
- [`ds_pbds.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_pbds.cpp)
- [`ds_segtree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_segtree.cpp)
- [`ds_segtree_pst.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/1-ds/ds_segtree_pst.cpp)
- [2-graph](https://github.com/manoflearning/cp-reference-codes/tree/main/src/2-graph)
- [`bcc.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/bcc.cpp)
- [`euler_circuit.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/euler_circuit.cpp)
- [`kth_shortest_path.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/kth_shortest_path.cpp)
- [`offline_dynamic_connectivity.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/offline_dynamic_connectivity.cpp)
- [`scc_2_sat.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/scc_2_sat.cpp)
- [`shortest_path.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/shortest_path.cpp)
- [`cc_bcc.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/cc_bcc.cpp)
- [`cc_scc.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/cc_scc.cpp)
- [`dyncon_off.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/dyncon_off.cpp)
- [`euler_circ.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/euler_circ.cpp)
- [`sat_2sat.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/sat_2sat.cpp)
- [`sp_basic.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/sp_basic.cpp)
- [`sp_kth.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/2-graph/sp_kth.cpp)
- [3-tree](https://github.com/manoflearning/cp-reference-codes/tree/main/src/3-tree)
- [`centroid_decomp.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/centroid_decomp.cpp)
- [`hld.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/hld.cpp)
- [`lca_sparse_table.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/lca_sparse_table.cpp)
- [`tree_composition.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_composition.cpp)
- [`tree_exchange_argument.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_exchange_argument.cpp)
- [`lca_sparse.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/lca_sparse.cpp)
- [`tree_centroid.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_centroid.cpp)
- [`tree_hld.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_hld.cpp)
- [`tree_vtree.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_vtree.cpp)
- [`tree_xchg.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/3-tree/tree_xchg.cpp)
- [4-optimizations](https://github.com/manoflearning/cp-reference-codes/tree/main/src/4-optimizations)
- [`flow.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/flow.cpp)
- [`hungarian.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/hungarian.cpp)
- [`assign_hung.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/assign_hung.cpp)
- [`flow_dinic.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/flow_dinic.cpp)
- [`flow_hk.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/flow_hk.cpp)
- [`flow_mcmf.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/4-optimizations/flow_mcmf.cpp)
- [5-string](https://github.com/manoflearning/cp-reference-codes/tree/main/src/5-string)
- [`aho_corasick.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/aho_corasick.cpp)
- [`kmp_algorithm.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/kmp_algorithm.cpp)
- [`manachers_algorithm.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/manachers_algorithm.cpp)
- [`rabin_karp_algorithm.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/rabin_karp_algorithm.cpp)
- [`suffix_array.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/suffix_array.cpp)
- [`trie.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/trie.cpp)
- [`z_algorithm.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/z_algorithm.cpp)
- [`hash_rk.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/hash_rk.cpp)
- [`match_ac.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/match_ac.cpp)
- [`match_kmp.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/match_kmp.cpp)
- [`match_z.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/match_z.cpp)
- [`pal_manacher.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/pal_manacher.cpp)
- [`str_trie.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/str_trie.cpp)
- [`suffix_sa.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/5-string/suffix_sa.cpp)
- [6-geometry](https://github.com/manoflearning/cp-reference-codes/tree/main/src/6-geometry)
- [`bulldozer_trick.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/bulldozer_trick.cpp)
- [`convex_hull.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/convex_hull.cpp)
- [`geom_ang_sort.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_ang_sort.cpp)
- [`geom_base.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_base.cpp)
- [`half_plane_intersection.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/half_plane_intersection.cpp)
- [`minimum_enclosing_circle.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/minimum_enclosing_circle.cpp)
- [`ray_casting.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/ray_casting.cpp)
- [`rotating_callipers.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/rotating_callipers.cpp)
- [`segment_intersection.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/segment_intersection.cpp)
- [`sort_by_angular.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/sort_by_angular.cpp)
- [`geom_bulldozer.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_bulldozer.cpp)
- [`geom_calipers.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_calipers.cpp)
- [`geom_hpi.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_hpi.cpp)
- [`geom_hull.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_hull.cpp)
- [`geom_mec.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_mec.cpp)
- [`geom_raycast.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_raycast.cpp)
- [`geom_seg_inter.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/6-geometry/geom_seg_inter.cpp)
- [7-math](https://github.com/manoflearning/cp-reference-codes/tree/main/src/7-math)
- [`comb_binom.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/7-math/comb_binom.cpp)
- [`comb_cat_der.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/7-math/comb_cat_der.cpp)
Expand All @@ -61,13 +65,13 @@ My implementations of various data structures and algorithms for competitive pro
- [`num.hpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/7-math/num.hpp)
- [8-misc](https://github.com/manoflearning/cp-reference-codes/tree/main/src/8-misc)
- [`dp_opt.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/dp_opt.cpp)
- [`fraction_data_type.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/fraction_data_type.cpp)
- [`kitamasa.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/kitamasa.cpp)
- [`lis_in_o_nlogn.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/lis_in_o_nlogn.cpp)
- [`random.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/random.cpp)
- [`diff_cons.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/diff_cons.cpp)
- [`num_frac.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/num_frac.cpp)
- [`rec_kitamasa.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/rec_kitamasa.cpp)
- [`rnd.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/rnd.cpp)
- [`rotation_matrix_manhattan_distance_chebyshev_distance.txt`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/rotation_matrix_manhattan_distance_chebyshev_distance.txt)
- [`search_ternary.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/search_ternary.cpp)
- [`seq_lis.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/seq_lis.cpp)
- [`simd.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/simd.cpp)
- [`sqrt_decomposition_mos_algorithm.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/sqrt_decomposition_mos_algorithm.cpp)
- [`sqrt_mo.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/sqrt_mo.cpp)
- [`stress_test.py`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/stress_test.py)
- [`system_of_difference_constraints.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/system_of_difference_constraints.cpp)
- [`ternary_search.cpp`](https://github.com/manoflearning/cp-reference-codes/blob/main/src/8-misc/ternary_search.cpp)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
88 changes: 0 additions & 88 deletions src/1-ds/segment_tree.cpp → src/1-ds/ds_segtree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,94 +138,6 @@ struct seg_tree_lz {
}
};

// what: keep all versions of point updates with range sum queries, plus kth by prefix sum.
// time: build O(n), update/query O(log n); memory: O(n log n)
// constraint: 1-indexed [1, n]; a[0] unused; kth needs all values >= 0.
// usage: seg_pst st; st.build(n, a); st.set(p, v); st.query(l, r, ver); st.kth(k, ver);
struct seg_pst {
struct node {
int l, r;
ll val;
};
int n;
vector<node> t;
vector<int> root;

void newnd() { t.push_back({-1, -1, 0}); }
void build(int n_, const vector<ll> &a) {
// goal: build initial version.
n = n_;
t.clear();
root.clear();
newnd();
root.push_back(0);
build(1, n, root[0], a);
}
void build(int l, int r, int v, const vector<ll> &a) {
// goal: build node v for range [l, r].
if (l == r) {
t[v].val = a[l];
return;
}
newnd();
t[v].l = sz(t) - 1;
newnd();
t[v].r = sz(t) - 1;
int mid = (l + r) >> 1;
build(l, mid, t[v].l, a);
build(mid + 1, r, t[v].r, a);
t[v].val = t[t[v].l].val + t[t[v].r].val;
}
void set(int p, ll val) {
// goal: create new version with a[p] = val.
newnd();
root.push_back(sz(t) - 1);
set(p, val, 1, n, root[sz(root) - 2], root.back());
}
void set(int p, ll val, int l, int r, int v1, int v2) {
// goal: update along path while sharing unchanged nodes.
if (p < l || r < p) {
t[v2] = t[v1];
return;
}
if (l == r) {
t[v2].val = val;
return;
}
int mid = (l + r) >> 1;
if (p <= mid) {
t[v2].r = t[v1].r;
newnd();
t[v2].l = sz(t) - 1;
set(p, val, l, mid, t[v1].l, t[v2].l);
} else {
t[v2].l = t[v1].l;
newnd();
t[v2].r = sz(t) - 1;
set(p, val, mid + 1, r, t[v1].r, t[v2].r);
}
t[v2].val = t[t[v2].l].val + t[t[v2].r].val;
}
ll query(int l, int r, int v, int nl, int nr) const {
// result: sum on [l, r] in a specific version.
if (r < nl || nr < l) return 0;
if (l <= nl && nr <= r) return t[v].val;
int mid = (nl + nr) >> 1;
return query(l, r, t[v].l, nl, mid) + query(l, r, t[v].r, mid + 1, nr);
}
ll query(int l, int r, int ver) const { return query(l, r, root[ver], 1, n); }
int kth(ll k, int v, int nl, int nr) const {
// result: smallest idx with prefix sum >= k (in this subtree).
assert(k > 0 && t[v].val >= k);
if (nl == nr) return nl;
int mid = (nl + nr) >> 1;
ll lv = t[t[v].l].val;
if (k <= lv) return kth(k, t[v].l, nl, mid);
return kth(k - lv, t[v].r, mid + 1, nr);
}
int kth(ll k, int ver) const { return kth(k, root[ver], 1, n); }
};

// what: sparse segment tree for large coordinate range (point add, range sum).
// time: update/query O(log R); memory: O(k log R)
// constraint: range [MAXL, MAXR], missing child => 0.
Expand Down
89 changes: 89 additions & 0 deletions src/1-ds/ds_segtree_pst.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#include "../0-common/common.hpp"

// what: persistent segment tree for point set with range sum queries, plus kth by prefix sum.
// time: build O(n), update/query O(log n); memory: O(n log n)
// constraint: 1-indexed [1, n]; a[0] unused; kth needs all values >= 0.
// usage: seg_pst st; st.build(n, a); st.set(p, v); st.query(l, r, ver); st.kth(k, ver);
struct seg_pst {
struct node {
int l, r;
ll val;
};
int n;
vector<node> t;
vector<int> root;

void newnd() { t.push_back({-1, -1, 0}); }
void build(int n_, const vector<ll> &a) {
// goal: build initial version.
n = n_;
t.clear();
root.clear();
newnd();
root.push_back(0);
build(1, n, root[0], a);
}
void build(int l, int r, int v, const vector<ll> &a) {
// goal: build node v for range [l, r].
if (l == r) {
t[v].val = a[l];
return;
}
newnd();
t[v].l = sz(t) - 1;
newnd();
t[v].r = sz(t) - 1;
int mid = (l + r) >> 1;
build(l, mid, t[v].l, a);
build(mid + 1, r, t[v].r, a);
t[v].val = t[t[v].l].val + t[t[v].r].val;
}
void set(int p, ll val) {
// goal: create new version with a[p] = val.
newnd();
root.push_back(sz(t) - 1);
set(p, val, 1, n, root[sz(root) - 2], root.back());
}
void set(int p, ll val, int l, int r, int v1, int v2) {
// goal: update along path while sharing unchanged nodes.
if (p < l || r < p) {
t[v2] = t[v1];
return;
}
if (l == r) {
t[v2].val = val;
return;
}
int mid = (l + r) >> 1;
if (p <= mid) {
t[v2].r = t[v1].r;
newnd();
t[v2].l = sz(t) - 1;
set(p, val, l, mid, t[v1].l, t[v2].l);
} else {
t[v2].l = t[v1].l;
newnd();
t[v2].r = sz(t) - 1;
set(p, val, mid + 1, r, t[v1].r, t[v2].r);
}
t[v2].val = t[t[v2].l].val + t[t[v2].r].val;
}
ll query(int l, int r, int v, int nl, int nr) const {
// result: sum on [l, r] in a specific version.
if (r < nl || nr < l) return 0;
if (l <= nl && nr <= r) return t[v].val;
int mid = (nl + nr) >> 1;
return query(l, r, t[v].l, nl, mid) + query(l, r, t[v].r, mid + 1, nr);
}
ll query(int l, int r, int ver) const { return query(l, r, root[ver], 1, n); }
int kth(ll k, int v, int nl, int nr) const {
// result: smallest idx with prefix sum >= k (in this subtree).
assert(k > 0 && t[v].val >= k);
if (nl == nr) return nl;
int mid = (nl + nr) >> 1;
ll lv = t[t[v].l].val;
if (k <= lv) return kth(k, t[v].l, nl, mid);
return kth(k - lv, t[v].r, mid + 1, nr);
}
int kth(ll k, int ver) const { return kth(k, root[ver], 1, n); }
};
File renamed without changes.
Loading