From 7dac2371a96b175757b5e56dcb05c2018eee17f4 Mon Sep 17 00:00:00 2001 From: manoflearning <77jwk0724@gmail.com> Date: Tue, 6 Jan 2026 01:52:19 +0900 Subject: [PATCH 1/2] refactor: 0-index to 1-index --- README.md | 4 ++ src/1-ds/ds_fenwick.cpp | 80 +++++++++++------------ src/1-ds/ds_merge_seg.cpp | 16 ++--- src/1-ds/ds_segtree.cpp | 42 ++++++------ src/4-optimizations/flow_dinic.cpp | 20 +++--- src/4-optimizations/flow_hk.cpp | 26 ++++---- src/4-optimizations/flow_mcmf.cpp | 28 ++++---- src/8-misc/diff_cons.cpp | 14 ++-- src/8-misc/sqrt_mo.cpp | 6 +- tests/1-ds/test_ds_fenwick.cpp | 60 ++++++++--------- tests/1-ds/test_ds_merge_seg.cpp | 28 ++++---- tests/1-ds/test_ds_segtree.cpp | 72 ++++++++++---------- tests/4-optimizations/test_flow_dinic.cpp | 12 ++-- tests/4-optimizations/test_flow_hk.cpp | 2 +- tests/4-optimizations/test_flow_mcmf.cpp | 12 ++-- tests/8-misc/test_diff_cons.cpp | 16 ++--- tests/8-misc/test_sqrt_mo.cpp | 8 +-- 17 files changed, 223 insertions(+), 223 deletions(-) diff --git a/README.md b/README.md index d60d191..93b2ace 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # CP Reference Codes My implementations of various data structures and algorithms for competitive programming. +## Indexing convention +- Default: **1-indexed** indices/vertices and **inclusive** ranges `[l, r]`. +- Exceptions: `src/5-string/*`, `src/1-ds/ds_pbds.cpp` are **0-indexed**; low-level pointer snippets (e.g. `src/8-misc/simd.cpp`) are 0-indexed. + ## Contents (GitHub links, `main`) - [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) diff --git a/src/1-ds/ds_fenwick.cpp b/src/1-ds/ds_fenwick.cpp index 6fd791e..be3cfc2 100644 --- a/src/1-ds/ds_fenwick.cpp +++ b/src/1-ds/ds_fenwick.cpp @@ -2,7 +2,7 @@ // what: maintain prefix sums with point updates and range sum queries. // time: build O(n), update/query O(log n); memory: O(n) -// constraint: 0-indexed; kth needs all values >= 0. +// constraint: 1-indexed [1, n]; a[0] unused; kth needs all values >= 0. // usage: fenwick fw; fw.build(a); fw.add(p, x); fw.sum(l, r); fw.kth(k); struct fenwick { int n; @@ -10,42 +10,41 @@ struct fenwick { void init(int n_) { // goal: allocate arrays for size n. n = n_; - a.assign(n, 0); - t.assign(n, 0); + a.assign(n + 1, 0); + t.assign(n + 1, 0); } void build(const vector &v) { // goal: build fenwick in O(n) from initial array. - n = sz(v); + n = sz(v) - 1; a = v; - t.assign(n, 0); - for (int i = 0; i < n; i++) { - t[i] += a[i]; - int j = i | (i + 1); - if (j < n) t[j] += t[i]; + t = a; + for (int i = 1; i <= n; i++) { + int j = i + (i & -i); + if (j <= n) t[j] += t[i]; } } void add(int p, ll val) { // goal: a[p] += val. a[p] += val; - for (int i = p; i < n; i |= i + 1) t[i] += val; + for (int i = p; i <= n; i += i & -i) t[i] += val; } void set(int p, ll val) { add(p, val - a[p]); } ll sum(int x) const { - // result: prefix sum on [0..x]. + // result: prefix sum on [1..x]. ll ret = 0; - for (int i = x; i >= 0; i = (i & (i + 1)) - 1) ret += t[i]; + for (int i = x; i > 0; i -= i & -i) ret += t[i]; return ret; } - ll sum(int l, int r) const { return sum(r) - (l ? sum(l - 1) : 0); } + ll sum(int l, int r) const { return sum(r) - sum(l - 1); } int kth(ll k) const { // result: smallest idx with prefix sum >= k. - assert(k > 0 && sum(n - 1) >= k); - int idx = -1; + assert(k > 0 && sum(n) >= k); + int idx = 0; int bit = 1; - while (bit < n) bit <<= 1; + while (bit <= n) bit <<= 1; for (; bit; bit >>= 1) { int nxt = idx + bit; - if (nxt < n && t[nxt] < k) { + if (nxt <= n && t[nxt] < k) { idx = nxt; k -= t[nxt]; } @@ -81,53 +80,50 @@ struct fenw_range { // 1-indexed // what: 2D point updates with axis-aligned rectangle sum queries. // time: build O(n m), update/query O(log n log m); memory: O(n m) -// constraint: 0-indexed; no bounds check. +// constraint: 1-indexed [1..n] x [1..m]; a[0][*], a[*][0] unused; no bounds check. // usage: fenw_2d fw; fw.build(a); fw.add(x, y, v); fw.sum(x1, y1, x2, y2); -struct fenw_2d { // 0-indexed +struct fenw_2d { // 1-indexed int n, m; vector> a, t; void init(int n_, int m_) { // goal: allocate arrays for n x m. n = n_, m = m_; - a.assign(n, vector(m, 0)); - t.assign(n, vector(m, 0)); + a.assign(n + 1, vector(m + 1, 0)); + t.assign(n + 1, vector(m + 1, 0)); } void build(const vector> &v) { // goal: build 2D fenwick in O(n*m). - n = sz(v); - m = n ? sz(v[0]) : 0; + n = sz(v) - 1; + m = n ? sz(v[1]) - 1 : 0; a = v; - t.assign(n, vector(m, 0)); - for (int i = 0; i < n; i++) { - for (int j = 0; j < m; j++) { - t[i][j] += a[i][j]; - int ni = i | (i + 1), nj = j | (j + 1); - if (ni < n) t[ni][j] += t[i][j]; - if (nj < m) t[i][nj] += t[i][j]; - if (ni < n && nj < m) t[ni][nj] -= t[i][j]; + t = a; + for (int i = 1; i <= n; i++) + for (int j = 1; j <= m; j++) { + int nj = j + (j & -j); + if (nj <= m) t[i][nj] += t[i][j]; + } + for (int j = 1; j <= m; j++) + for (int i = 1; i <= n; i++) { + int ni = i + (i & -i); + if (ni <= n) t[ni][j] += t[i][j]; } - } } void add(int x, int y, ll val) { // goal: a[x][y] += val. a[x][y] += val; - for (int i = x; i < n; i |= i + 1) - for (int j = y; j < m; j |= j + 1) t[i][j] += val; + for (int i = x; i <= n; i += i & -i) + for (int j = y; j <= m; j += j & -j) t[i][j] += val; } void set(int x, int y, ll val) { add(x, y, val - a[x][y]); } ll sum(int x, int y) const { - // result: sum over rectangle [0..x] x [0..y]. + // result: sum over rectangle [1..x] x [1..y]. ll ret = 0; - for (int i = x; i >= 0; i = (i & (i + 1)) - 1) - for (int j = y; j >= 0; j = (j & (j + 1)) - 1) ret += t[i][j]; + for (int i = x; i > 0; i -= i & -i) + for (int j = y; j > 0; j -= j & -j) ret += t[i][j]; return ret; } ll sum(int x1, int y1, int x2, int y2) const { // result: sum over rectangle [x1..x2] x [y1..y2]. - ll ret = sum(x2, y2); - if (x1) ret -= sum(x1 - 1, y2); - if (y1) ret -= sum(x2, y1 - 1); - if (x1 && y1) ret += sum(x1 - 1, y1 - 1); - return ret; + return sum(x2, y2) - sum(x1 - 1, y2) - sum(x2, y1 - 1) + sum(x1 - 1, y1 - 1); } }; diff --git a/src/1-ds/ds_merge_seg.cpp b/src/1-ds/ds_merge_seg.cpp index 8ece15c..f68ed23 100644 --- a/src/1-ds/ds_merge_seg.cpp +++ b/src/1-ds/ds_merge_seg.cpp @@ -3,20 +3,20 @@ constexpr int MAX_MST = 1 << 17; // what: static range count queries by storing sorted lists on a segment tree. // time: build O(n log n), query O(log^2 n); memory: O(n log n) -// constraint: MAX_MST >= n; values fit in int; 0-indexed [l, r]; build once. +// constraint: MAX_MST >= n; values fit in int; 1-indexed [1..n]; build once. // usage: merge_seg st; st.build(a); st.query(l, r, k); struct merge_seg { vector t[MAX_MST << 1]; void build(const vector &a) { // goal: build sorted lists for each node. - for (int i = 0; i < sz(a); i++) - t[i + MAX_MST].push_back(a[i]); + for (int i = 1; i < sz(a); i++) + t[i + MAX_MST - 1].push_back(a[i]); for (int i = MAX_MST - 1; i >= 1; i--) { t[i].resize(sz(t[i << 1]) + sz(t[i << 1 | 1])); merge(all(t[i << 1]), all(t[i << 1 | 1]), t[i].begin()); } } - int query(int l, int r, int k, int v = 1, int nl = 0, int nr = MAX_MST - 1) const { + int query(int l, int r, int k, int v = 1, int nl = 1, int nr = MAX_MST) const { // result: count of elements > k in [l, r]. if (nr < l || r < nl) return 0; if (l <= nl && nr <= r) @@ -28,14 +28,14 @@ struct merge_seg { // what: iterative merge sort tree for static range count queries. // time: build O(n log n), query O(log^2 n); memory: O(n log n) -// constraint: MAX_MST >= n; values fit in int; 0-indexed [l, r]; build once. +// constraint: MAX_MST >= n; values fit in int; 1-indexed [1..n]; build once. // usage: merge_seg_it st; st.build(a); st.query(l, r, k); struct merge_seg_it { vector t[MAX_MST << 1]; void build(const vector &a) { // goal: build sorted lists for each node. - for (int i = 0; i < sz(a); i++) - t[i + MAX_MST].push_back(a[i]); + for (int i = 1; i < sz(a); i++) + t[i + MAX_MST - 1].push_back(a[i]); for (int i = MAX_MST - 1; i >= 1; i--) { t[i].resize(sz(t[i << 1]) + sz(t[i << 1 | 1])); merge(all(t[i << 1]), all(t[i << 1 | 1]), t[i].begin()); @@ -43,7 +43,7 @@ struct merge_seg_it { } int query(int l, int r, int k) const { // result: count of elements > k in [l, r]. - l += MAX_MST, r += MAX_MST; + l += MAX_MST - 1, r += MAX_MST - 1; int ret = 0; while (l <= r) { if (l & 1) ret += int(t[l].end() - upper_bound(all(t[l]), k)), l++; diff --git a/src/1-ds/ds_segtree.cpp b/src/1-ds/ds_segtree.cpp index 2b0abfc..39644e4 100644 --- a/src/1-ds/ds_segtree.cpp +++ b/src/1-ds/ds_segtree.cpp @@ -32,26 +32,26 @@ struct seg_tree { // what: iterative segment tree for point update and range sum. // time: build O(n), update/query O(log n); memory: O(n) -// constraint: 0-indexed [l, r). +// constraint: 1-indexed [1, n]; a[0] unused. // usage: seg_tree_it st; st.build(a); st.set(p, v); st.query(l, r); -struct seg_tree_it { // 0-indexed +struct seg_tree_it { // 1-indexed int n; vector t; void build(const vector &a) { - // goal: build tree from 0-indexed array. - n = sz(a); + // goal: build tree from 1-indexed array. + n = sz(a) - 1; t.assign(2 * n, 0); - for (int i = 0; i < n; i++) t[n + i] = a[i]; + for (int i = 1; i <= n; i++) t[n + i - 1] = a[i]; for (int i = n - 1; i >= 1; i--) t[i] = t[i << 1] + t[i << 1 | 1]; } void set(int p, ll val) { // goal: set a[p] = val. - for (t[p += n] = val; p > 1; p >>= 1) t[p >> 1] = t[p] + t[p ^ 1]; + for (t[p += n - 1] = val; p > 1; p >>= 1) t[p >> 1] = t[p] + t[p ^ 1]; } ll query(int l, int r) const { - // result: sum on [l, r). + // result: sum on [l, r]. ll ret = 0; - for (l += n, r += n; l < r; l >>= 1, r >>= 1) { + for (l += n - 1, r += n; l < r; l >>= 1, r >>= 1) { if (l & 1) ret += t[l++]; if (r & 1) ret += t[--r]; } @@ -183,18 +183,18 @@ struct seg_sparse { // what: 2D point updates with rectangle sum queries on a square grid. // time: build O(n^2), update/query O(log^2 n); memory: O(n^2) -// constraint: 0-indexed square n x n. +// constraint: 1-indexed square [1..n] x [1..n]; a[0][*], a[*][0] unused. // usage: seg_2d st; st.build(a); st.set(x, y, v); st.query(x1, x2, y1, y2); -struct seg_2d { // 0-indexed +struct seg_2d { // 1-indexed int n; vector> t; void build(const vector> &a) { // goal: build 2D tree from initial grid. - n = sz(a); + n = sz(a) - 1; t.assign(2 * n, vector(2 * n, 0)); - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) - t[i + n][j + n] = a[i][j]; + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) + t[i + n - 1][j + n - 1] = a[i][j]; for (int i = n; i < 2 * n; i++) for (int j = n - 1; j > 0; j--) t[i][j] = t[i][j << 1] + t[i][j << 1 | 1]; @@ -204,6 +204,7 @@ struct seg_2d { // 0-indexed } void set(int x, int y, ll val) { // goal: set a[x][y] = val. + x--, y--; t[x + n][y + n] = val; for (int j = y + n; j > 1; j >>= 1) t[x + n][j >> 1] = t[x + n][j] + t[x + n][j ^ 1]; @@ -222,6 +223,7 @@ struct seg_2d { // 0-indexed } ll query(int x1, int x2, int y1, int y2) const { // result: sum on rectangle [x1..x2] x [y1..y2]. + x1--, x2--, y1--, y2--; ll ret = 0; for (x1 += n, x2 += n + 1; x1 < x2; x1 >>= 1, x2 >>= 1) { if (x1 & 1) ret += qry1d(x1++, y1, y2); @@ -233,9 +235,9 @@ struct seg_2d { // 0-indexed // what: 2D segment tree with coordinate compression for sparse updates/queries. // time: prep O(q log q), update/query O(log^2 n); memory: O(q log q) -// constraint: call mark_set/mark_qry first, then prep, then set/query. +// constraint: x is 1-indexed [1..n]; y is coordinate value; call mark_set/mark_qry first, then prep, then set/query. // usage: seg2d_comp st(n); st.mark_set(x, y); st.mark_qry(x1, x2, y1, y2); st.prep(); st.set(x, y, v); st.query(x1, x2, y1, y2); -struct seg2d_comp { // 0-indexed +struct seg2d_comp { // x: 1-indexed int n; vector> a; vector> used; @@ -243,11 +245,11 @@ struct seg2d_comp { // 0-indexed seg2d_comp(int n) : n(n), a(2 * n), used(2 * n) {} void mark_set(int x, int y) { // goal: record y-coordinates that will be updated. - for (x += n; x >= 1; x >>= 1) used[x].push_back(y); + for (x += n - 1; x >= 1; x >>= 1) used[x].push_back(y); } void mark_qry(int x1, int x2, int y1, int y2) { // goal: record y-coordinates needed for queries. - for (x1 += n, x2 += n + 1; x1 < x2; x1 >>= 1, x2 >>= 1) { + for (x1 += n - 1, x2 += n; x1 < x2; x1 >>= 1, x2 >>= 1) { if (x1 & 1) { used[x1].push_back(y1); used[x1++].push_back(y2); @@ -274,7 +276,7 @@ struct seg2d_comp { // 0-indexed ll k = (ll)x << 32 | (unsigned)y; ll d = v - mp[k]; mp[k] = v; - for (x += n; x >= 1; x >>= 1) { + for (x += n - 1; x >= 1; x >>= 1) { int i = lower_bound(all(used[x]), y) - used[x].begin() + sz(used[x]); for (a[x][i] += d; i > 1; i >>= 1) a[x][i >> 1] = a[x][i] + a[x][i ^ 1]; @@ -294,7 +296,7 @@ struct seg2d_comp { // 0-indexed ll query(int x1, int x2, int y1, int y2) const { // result: sum on rectangle [x1..x2] x [y1..y2]. ll ret = 0; - for (x1 += n, x2 += n + 1; x1 < x2; x1 >>= 1, x2 >>= 1) { + for (x1 += n - 1, x2 += n; x1 < x2; x1 >>= 1, x2 >>= 1) { if (x1 & 1) ret += qry1d(x1++, y1, y2); if (x2 & 1) ret += qry1d(--x2, y1, y2); } diff --git a/src/4-optimizations/flow_dinic.cpp b/src/4-optimizations/flow_dinic.cpp index 93b59c6..d23f4c1 100644 --- a/src/4-optimizations/flow_dinic.cpp +++ b/src/4-optimizations/flow_dinic.cpp @@ -2,7 +2,7 @@ // what: compute maximum flow in a directed graph (Dinic). // time: O(E V^2) worst; memory: O(E) -// constraint: 0-based; cap >= 0. +// constraint: 1-indexed [1..n]; cap >= 0. // usage: dinic mf(n); mf.add_edge(u, v, cap); ll f = mf.max_flow(s, t); struct dinic { static constexpr ll INF = (1LL << 62); @@ -22,7 +22,7 @@ struct dinic { dinic(int n = 0) { init(n); } void init(int n_) { n = n_; - g.assign(n, {}); + g.assign(n + 1, {}); } edge_ref add_edge(int u, int v, ll cap) { // goal: add forward + reverse edge @@ -47,7 +47,7 @@ struct dinic { bool bfs(int s, int t) { // goal: build level graph - level.assign(n, -1); + level.assign(n + 1, -1); queue q; level[s] = 0; q.push(s); @@ -80,7 +80,7 @@ struct dinic { if (s == t) return 0; // edge: no flow needed ll flow = 0; while (flow < limit && bfs(s, t)) { - work.assign(n, 0); + work.assign(n + 1, 0); while (flow < limit) { ll pushed = dfs(s, t, limit - flow); if (pushed == 0) break; @@ -93,7 +93,7 @@ struct dinic { // what: find feasible max flow with lower/upper bounds via transformation. // time: dominated by dinic; memory: O(E) -// constraint: 0-based; 0 <= lo <= hi; single-use (call init(n) to reuse). +// constraint: 1-indexed [1..n]; 0 <= lo <= hi; single-use (call init(n) to reuse). // usage: lr_dinic f(n); f.add_edge(u, v, lo, hi); auto [ok, fl] = f.max_flow(s, t); struct lr_dinic { static constexpr ll INF = dinic::INF; @@ -112,7 +112,7 @@ struct lr_dinic { void init(int n_) { n = n_; mf.init(n + 2); - demand.assign(n, 0); + demand.assign(n + 1, 0); edges.clear(); } int add_edge(int u, int v, ll lo, ll hi) { @@ -129,8 +129,8 @@ struct lr_dinic { ll add_demands(vector &aux) { // goal: connect ss/tt for feasible circulation ll total = 0; - int ss = n, tt = n + 1; - for (int i = 0; i < n; i++) { + int ss = n + 1, tt = n + 2; + for (int i = 1; i <= n; i++) { if (demand[i] > 0) { aux.push_back(mf.add_edge(ss, i, demand[i])); total += demand[i]; @@ -145,7 +145,7 @@ struct lr_dinic { vector aux; aux.reserve(n); ll total = add_demands(aux); - int ss = n, tt = n + 1; + int ss = n + 1, tt = n + 2; ll flow = mf.max_flow(ss, tt); for (auto ref : aux) mf.clear_edge(ref); return flow == total; @@ -154,7 +154,7 @@ struct lr_dinic { if (s == t) return {feasible(), 0}; // edge: trivial s == t vector aux; aux.reserve(n + 1); - int ss = n, tt = n + 1; + int ss = n + 1, tt = n + 2; auto ts = mf.add_edge(t, s, INF); ll total = add_demands(aux); ll flow = mf.max_flow(ss, tt); diff --git a/src/4-optimizations/flow_hk.cpp b/src/4-optimizations/flow_hk.cpp index 5490797..c3ec493 100644 --- a/src/4-optimizations/flow_hk.cpp +++ b/src/4-optimizations/flow_hk.cpp @@ -2,7 +2,7 @@ // what: maximum bipartite matching (Hopcroft-Karp). // time: O(E sqrt V); memory: O(E) -// constraint: 0-based; left [0..n_l-1], right [0..n_r-1] +// constraint: 1-indexed; left [1..n_l], right [1..n_r] // usage: hk bm(n_l, n_r); bm.add_edge(l, r); int m = bm.max_matching(); struct hk { int n_l, n_r; @@ -13,10 +13,10 @@ struct hk { void init(int n_l_, int n_r_) { n_l = n_l_; n_r = n_r_; - g.assign(n_l, {}); - dist.assign(n_l, 0); - match_l.assign(n_l, -1); - match_r.assign(n_r, -1); + g.assign(n_l + 1, {}); + dist.assign(n_l + 1, 0); + match_l.assign(n_l + 1, 0); + match_r.assign(n_r + 1, 0); } void add_edge(int l, int r) { // goal: add edge from left to right @@ -27,8 +27,8 @@ struct hk { // goal: build layers for shortest augmenting paths queue q; fill(all(dist), -1); - for (int i = 0; i < n_l; i++) { - if (match_l[i] == -1) { + for (int i = 1; i <= n_l; i++) { + if (match_l[i] == 0) { dist[i] = 0; q.push(i); } @@ -39,7 +39,7 @@ struct hk { q.pop(); for (int r : g[v]) { int u = match_r[r]; - if (u == -1) { + if (u == 0) { found = true; } else if (dist[u] == -1) { dist[u] = dist[v] + 1; @@ -52,7 +52,7 @@ struct hk { bool dfs(int v) { for (int r : g[v]) { int u = match_r[r]; - if (u == -1 || (dist[u] == dist[v] + 1 && dfs(u))) { + if (u == 0 || (dist[u] == dist[v] + 1 && dfs(u))) { match_l[v] = r; match_r[r] = v; return true; @@ -63,12 +63,12 @@ struct hk { } int max_matching() { // goal: compute maximum matching size - fill(all(match_l), -1); - fill(all(match_r), -1); + fill(all(match_l), 0); + fill(all(match_r), 0); int match = 0; while (bfs()) { - for (int i = 0; i < n_l; i++) { - if (match_l[i] == -1 && dfs(i)) match++; + for (int i = 1; i <= n_l; i++) { + if (match_l[i] == 0 && dfs(i)) match++; } } return match; diff --git a/src/4-optimizations/flow_mcmf.cpp b/src/4-optimizations/flow_mcmf.cpp index 00647d3..a58bcfc 100644 --- a/src/4-optimizations/flow_mcmf.cpp +++ b/src/4-optimizations/flow_mcmf.cpp @@ -2,7 +2,7 @@ // what: compute min-cost max-flow using potentials and Dijkstra. // time: O(F E log V); memory: O(E) -// constraint: 0-based; cap >= 0; no negative cycle reachable from s. +// constraint: 1-indexed [1..n]; cap >= 0; no negative cycle reachable from s. // usage: mcmf mf(n); mf.add_edge(u, v, cap, cost); pll r = mf.min_cost_mf(s, t); // usage: init_pot = false if all costs >= 0 (faster) struct mcmf { @@ -22,7 +22,7 @@ struct mcmf { mcmf(int n = 0) { init(n); } void init(int n_) { n = n_; - g.assign(n, {}); + g.assign(n + 1, {}); } edge_ref add_edge(int u, int v, ll cap, ll cost) { // goal: add forward + reverse edge with costs @@ -47,13 +47,13 @@ struct mcmf { pll min_cost_mf(int s, int t, ll max_f = INF, bool init_pot = true) { ll flow = 0, cost = 0; - vector pot(n, 0), dist(n); - vector pv(n), pe(n); + vector pot(n + 1, 0), dist(n + 1); + vector pv(n + 1), pe(n + 1); if (init_pot) { // goal: initial potentials for negative costs - vector d(n, INF); - vector in_q(n, 0); + vector d(n + 1, INF); + vector in_q(n + 1, 0); queue q; d[s] = 0; q.push(s); @@ -73,7 +73,7 @@ struct mcmf { } } } - for (int i = 0; i < n; i++) + for (int i = 1; i <= n; i++) if (d[i] < INF) pot[i] = d[i]; } while (flow < max_f) { @@ -99,7 +99,7 @@ struct mcmf { } } if (dist[t] == INF) break; // edge: no more augmenting paths - for (int i = 0; i < n; i++) + for (int i = 1; i <= n; i++) if (dist[i] < INF) pot[i] += dist[i]; ll add = max_f - flow; @@ -122,7 +122,7 @@ struct mcmf { // what: find min-cost flow with lower/upper bounds via transformation. // time: dominated by mcmf; memory: O(E) -// constraint: 0-based; 0 <= lo <= hi; no negative cycle; single-use (call init(n) to reuse). +// constraint: 1-indexed [1..n]; 0 <= lo <= hi; no negative cycle; single-use (call init(n) to reuse). // usage: lr_mcmf f(n); f.add_edge(u, v, lo, hi, cost); auto [ok, r] = f.max_flow(s, t); struct lr_mcmf { static constexpr ll INF = mcmf::INF; @@ -142,7 +142,7 @@ struct lr_mcmf { void init(int n_) { n = n_; mf.init(n + 2); - demand.assign(n, 0); + demand.assign(n + 1, 0); edges.clear(); base_cost = 0; } @@ -161,8 +161,8 @@ struct lr_mcmf { ll add_demands(vector &aux) { // goal: connect ss/tt for feasible circulation ll total = 0; - int ss = n, tt = n + 1; - for (int i = 0; i < n; i++) { + int ss = n + 1, tt = n + 2; + for (int i = 1; i <= n; i++) { if (demand[i] > 0) { aux.push_back(mf.add_edge(ss, i, demand[i], 0)); total += demand[i]; @@ -177,7 +177,7 @@ struct lr_mcmf { vector aux; aux.reserve(n); ll total = add_demands(aux); - int ss = n, tt = n + 1; + int ss = n + 1, tt = n + 2; pll res = mf.min_cost_mf(ss, tt, total, init_pot); for (auto ref : aux) mf.clear_edge(ref); if (res.fr != total) return {false, 0}; @@ -190,7 +190,7 @@ struct lr_mcmf { } vector aux; aux.reserve(n + 1); - int ss = n, tt = n + 1; + int ss = n + 1, tt = n + 2; auto ts = mf.add_edge(t, s, INF, 0); ll total = add_demands(aux); pll res = mf.min_cost_mf(ss, tt, total, init_pot); diff --git a/src/8-misc/diff_cons.cpp b/src/8-misc/diff_cons.cpp index 7600cd0..981dd8c 100644 --- a/src/8-misc/diff_cons.cpp +++ b/src/8-misc/diff_cons.cpp @@ -2,7 +2,7 @@ // what: solve difference constraints x_v - x_u <= w with Bellman-Ford. // time: O(nm) via Bellman-Ford; memory: O(n+m) -// constraint: 0-indexed vars; no overflow in relaxations. +// constraint: 1-indexed vars [1..n]; no overflow in relaxations. // usage: diff_cons dc(n); dc.add_le(u,v,w); bool ok=dc.solve(); auto x=dc.val(); struct diff_cons { struct edge { @@ -17,8 +17,8 @@ struct diff_cons { diff_cons(int n_ = 0) { init(n_); } void init(int n_) { n = n_; - g.assign(n, {}); - dist.assign(n, 0); + g.assign(n + 1, {}); + dist.assign(n + 1, 0); } void add_le(int u, int v, ll w) { // goal: x_v - x_u <= w @@ -36,10 +36,10 @@ struct diff_cons { bool solve() { // invariant: dist is current potential, all nodes reachable from super source - dist.assign(n, 0); - for (int it = 0; it < n; it++) { + dist.assign(n + 1, 0); + for (int it = 1; it <= n; it++) { bool upd = false; - for (int v = 0; v < n; v++) { + for (int v = 1; v <= n; v++) { for (const auto &e : g[v]) { if (dist[e.to] > dist[v] + e.w) { dist[e.to] = dist[v] + e.w; @@ -49,7 +49,7 @@ struct diff_cons { } if (!upd) return true; } - for (int v = 0; v < n; v++) { + for (int v = 1; v <= n; v++) { for (const auto &e : g[v]) { if (dist[e.to] > dist[v] + e.w) return false; } diff --git a/src/8-misc/sqrt_mo.cpp b/src/8-misc/sqrt_mo.cpp index 6ee630d..be43adf 100644 --- a/src/8-misc/sqrt_mo.cpp +++ b/src/8-misc/sqrt_mo.cpp @@ -2,7 +2,7 @@ // what: reorder offline range queries to minimize add/del operations (Mo's algorithm). // time: O((n+q) * sqrt(n)); memory: O(q) -// constraint: 0-indexed, inclusive [l, r]; add/del by index. +// constraint: 1-indexed, inclusive [l, r]; add/del by index. // usage: mo solver(n); solver.add_query(l, r, idx); solver.run(add, del, out); struct mo { struct qry { @@ -24,11 +24,11 @@ struct mo { void run(Add add, Del del, Out out) { // goal: process queries in Mo order with callbacks. sort(all(q), [&](const qry &a, const qry &b) { - int ba = a.l / bs, bb = b.l / bs; + int ba = (a.l - 1) / bs, bb = (b.l - 1) / bs; if (ba != bb) return ba < bb; return (ba & 1) ? a.r > b.r : a.r < b.r; }); - int l = 0, r = -1; + int l = 1, r = 0; for (const auto &qr : q) { while (l > qr.l) add(--l); while (r < qr.r) add(++r); diff --git a/tests/1-ds/test_ds_fenwick.cpp b/tests/1-ds/test_ds_fenwick.cpp index 77f7b4c..a8e5823 100644 --- a/tests/1-ds/test_ds_fenwick.cpp +++ b/tests/1-ds/test_ds_fenwick.cpp @@ -19,7 +19,7 @@ ll sum_1d(const vector &a, int l, int r) { int kth_naive(const vector &a, ll k) { ll cur = 0; - for (int i = 0; i < sz(a); i++) { + for (int i = 1; i < sz(a); i++) { cur += a[i]; if (cur >= k) return i; } @@ -35,20 +35,20 @@ ll sum_2d(const vector> &a, int x1, int y1, int x2, int y2) { void test_fenwick_basic() { fenwick fw; - vector a = {5}; + vector a = {0, 5}; fw.build(a); - assert(fw.sum(0, 0) == 5); - assert(fw.kth(1) == 0); - fw.set(0, 0); - assert(fw.sum(0, 0) == 0); - fw.add(0, 7); - assert(fw.sum(0, 0) == 7); + assert(fw.sum(1, 1) == 5); + assert(fw.kth(1) == 1); + fw.set(1, 0); + assert(fw.sum(1, 1) == 0); + fw.add(1, 7); + assert(fw.sum(1, 1) == 7); } void test_fenwick_random() { int n = 50; - vector a(n); - for (int i = 0; i < n; i++) a[i] = rnd(0, 5); + vector a(n + 1, 0); + for (int i = 1; i <= n; i++) a[i] = rnd(0, 5); fenwick fw; fw.build(a); @@ -56,22 +56,22 @@ void test_fenwick_random() { for (int it = 0; it < 5000; it++) { int op = (int)rnd(0, 3); if (op == 0) { - int p = (int)rnd(0, n - 1); + int p = (int)rnd(1, n); ll v = rnd(0, 5); a[p] += v; fw.add(p, v); } else if (op == 1) { - int p = (int)rnd(0, n - 1); + int p = (int)rnd(1, n); ll v = rnd(0, 10); a[p] = v; fw.set(p, v); } else if (op == 2) { - int l = (int)rnd(0, n - 1); - int r = (int)rnd(l, n - 1); + int l = (int)rnd(1, n); + int r = (int)rnd(l, n); assert(fw.sum(l, r) == sum_1d(a, l, r)); } else { ll tot = 0; - for (ll v : a) tot += v; + for (int i = 1; i <= n; i++) tot += a[i]; if (tot == 0) continue; ll k = rnd(1, tot); assert(fw.kth(k) == kth_naive(a, k)); @@ -109,18 +109,18 @@ void test_fenwick_rp_random() { void test_fenwick_2d_basic() { fenw_2d fw; - vector> a = {{3}}; + vector> a = {{0, 0}, {0, 3}}; fw.build(a); - assert(fw.sum(0, 0, 0, 0) == 3); - fw.set(0, 0, -2); - assert(fw.sum(0, 0, 0, 0) == -2); + assert(fw.sum(1, 1, 1, 1) == 3); + fw.set(1, 1, -2); + assert(fw.sum(1, 1, 1, 1) == -2); } void test_fenwick_2d_random() { int n = 8, m = 7; - vector> a(n, vector(m, 0)); - for (int i = 0; i < n; i++) - for (int j = 0; j < m; j++) a[i][j] = rnd(-3, 3); + vector> a(n + 1, vector(m + 1, 0)); + for (int i = 1; i <= n; i++) + for (int j = 1; j <= m; j++) a[i][j] = rnd(-3, 3); fenw_2d fw; fw.build(a); @@ -128,22 +128,22 @@ void test_fenwick_2d_random() { for (int it = 0; it < 4000; it++) { int op = (int)rnd(0, 2); if (op == 0) { - int x = (int)rnd(0, n - 1); - int y = (int)rnd(0, m - 1); + int x = (int)rnd(1, n); + int y = (int)rnd(1, m); ll v = rnd(-3, 3); a[x][y] += v; fw.add(x, y, v); } else if (op == 1) { - int x = (int)rnd(0, n - 1); - int y = (int)rnd(0, m - 1); + int x = (int)rnd(1, n); + int y = (int)rnd(1, m); ll v = rnd(-5, 5); a[x][y] = v; fw.set(x, y, v); } else { - int x1 = (int)rnd(0, n - 1); - int x2 = (int)rnd(x1, n - 1); - int y1 = (int)rnd(0, m - 1); - int y2 = (int)rnd(y1, m - 1); + int x1 = (int)rnd(1, n); + int x2 = (int)rnd(x1, n); + int y1 = (int)rnd(1, m); + int y2 = (int)rnd(y1, m); assert(fw.sum(x1, y1, x2, y2) == sum_2d(a, x1, y1, x2, y2)); } } diff --git a/tests/1-ds/test_ds_merge_seg.cpp b/tests/1-ds/test_ds_merge_seg.cpp index bdd27a2..ffd9aab 100644 --- a/tests/1-ds/test_ds_merge_seg.cpp +++ b/tests/1-ds/test_ds_merge_seg.cpp @@ -18,48 +18,48 @@ int count_greater(const vector &a, int l, int r, int k) { } void test_merge_sort_tree_basic() { - vector a = {5}; + vector a = {0, 5}; merge_seg st; st.build(a); - assert(st.query(0, 0, 4) == 1); - assert(st.query(0, 0, 5) == 0); + assert(st.query(1, 1, 4) == 1); + assert(st.query(1, 1, 5) == 0); } void test_merge_sort_tree_random() { int n = 60; - vector a(n); - for (int i = 0; i < n; i++) a[i] = (int)rnd(-10, 10); + vector a(n + 1, 0); + for (int i = 1; i <= n; i++) a[i] = (int)rnd(-10, 10); merge_seg st; st.build(a); for (int it = 0; it < 4000; it++) { - int l = (int)rnd(0, n - 1); - int r = (int)rnd(l, n - 1); + int l = (int)rnd(1, n); + int r = (int)rnd(l, n); int k = (int)rnd(-10, 10); assert(st.query(l, r, k) == count_greater(a, l, r, k)); } } void test_merge_sort_tree_iter_basic() { - vector a = {2}; + vector a = {0, 2}; merge_seg_it st; st.build(a); - assert(st.query(0, 0, 1) == 1); - assert(st.query(0, 0, 2) == 0); + assert(st.query(1, 1, 1) == 1); + assert(st.query(1, 1, 2) == 0); } void test_merge_sort_tree_iter_random() { int n = 60; - vector a(n); - for (int i = 0; i < n; i++) a[i] = (int)rnd(-10, 10); + vector a(n + 1, 0); + for (int i = 1; i <= n; i++) a[i] = (int)rnd(-10, 10); merge_seg_it st; st.build(a); for (int it = 0; it < 4000; it++) { - int l = (int)rnd(0, n - 1); - int r = (int)rnd(l, n - 1); + int l = (int)rnd(1, n); + int r = (int)rnd(l, n); int k = (int)rnd(-10, 10); assert(st.query(l, r, k) == count_greater(a, l, r, k)); } diff --git a/tests/1-ds/test_ds_segtree.cpp b/tests/1-ds/test_ds_segtree.cpp index afeab84..1b05397 100644 --- a/tests/1-ds/test_ds_segtree.cpp +++ b/tests/1-ds/test_ds_segtree.cpp @@ -59,18 +59,18 @@ void test_segt_random() { } void test_segti_basic() { - vector a = {4}; + vector a = {0, 4}; seg_tree_it st; st.build(a); - assert(st.query(0, 1) == 4); - st.set(0, 1); - assert(st.query(0, 1) == 1); + assert(st.query(1, 1) == 4); + st.set(1, 1); + assert(st.query(1, 1) == 1); } void test_segti_random() { int n = 50; - vector a(n, 0); - for (int i = 0; i < n; i++) a[i] = rnd(-5, 5); + vector a(n + 1, 0); + for (int i = 1; i <= n; i++) a[i] = rnd(-5, 5); seg_tree_it st; st.build(a); @@ -78,16 +78,14 @@ void test_segti_random() { for (int it = 0; it < 5000; it++) { int op = (int)rnd(0, 1); if (op == 0) { - int p = (int)rnd(0, n - 1); + int p = (int)rnd(1, n); ll v = rnd(-5, 5); a[p] = v; st.set(p, v); } else { - int l = (int)rnd(0, n - 1); - int r = (int)rnd(l, n - 1); - ll ret = 0; - for (int i = l; i <= r; i++) ret += a[i]; - assert(st.query(l, r + 1) == ret); + int l = (int)rnd(1, n); + int r = (int)rnd(l, n); + assert(st.query(l, r) == sum_range(a, l, r)); } } } @@ -198,19 +196,19 @@ ll sum_rect(const vector> &a, int x1, int y1, int x2, int y2) { } void test_seg2d_basic() { - vector> a = {{7}}; + vector> a = {{0, 0}, {0, 7}}; seg_2d st; st.build(a); - assert(st.query(0, 0, 0, 0) == 7); - st.set(0, 0, -1); - assert(st.query(0, 0, 0, 0) == -1); + assert(st.query(1, 1, 1, 1) == 7); + st.set(1, 1, -1); + assert(st.query(1, 1, 1, 1) == -1); } void test_seg2d_random() { int n = 7; - vector> a(n, vector(n, 0)); - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) a[i][j] = rnd(-3, 3); + vector> a(n + 1, vector(n + 1, 0)); + for (int i = 1; i <= n; i++) + for (int j = 1; j <= n; j++) a[i][j] = rnd(-3, 3); seg_2d st; st.build(a); @@ -218,16 +216,16 @@ void test_seg2d_random() { for (int it = 0; it < 3000; it++) { int op = (int)rnd(0, 1); if (op == 0) { - int x = (int)rnd(0, n - 1); - int y = (int)rnd(0, n - 1); + int x = (int)rnd(1, n); + int y = (int)rnd(1, n); ll v = rnd(-5, 5); a[x][y] = v; st.set(x, y, v); } else { - int x1 = (int)rnd(0, n - 1); - int x2 = (int)rnd(x1, n - 1); - int y1 = (int)rnd(0, n - 1); - int y2 = (int)rnd(y1, n - 1); + int x1 = (int)rnd(1, n); + int x2 = (int)rnd(x1, n); + int y1 = (int)rnd(1, n); + int y2 = (int)rnd(y1, n); assert(st.query(x1, x2, y1, y2) == sum_rect(a, x1, y1, x2, y2)); } } @@ -243,10 +241,10 @@ void test_seg2dc_basic() { int n = 1; seg2d_comp st(n); vector ops; - ops.push_back({0, 0, 0, 0, 0, 5}); - ops.push_back({1, 0, 0, 0, 0, 0}); - ops.push_back({0, 0, 0, 0, 0, -2}); - ops.push_back({1, 0, 0, 0, 0, 0}); + ops.push_back({0, 1, 0, 1, 0, 5}); + ops.push_back({1, 1, 1, 1, 1, 0}); + ops.push_back({0, 1, 0, 1, 0, -2}); + ops.push_back({1, 1, 1, 1, 1, 0}); for (auto &op : ops) { if (op.type == 0) st.mark_set(op.x1, op.y1); @@ -254,7 +252,7 @@ void test_seg2dc_basic() { } st.prep(); - vector> a(n, vector(n, 0)); + vector> a(n + 1, vector(n + 1, 0)); for (auto &op : ops) { if (op.type == 0) { a[op.x1][op.y1] = op.val; @@ -281,15 +279,15 @@ void test_seg2dc_random() { for (int i = 0; i < q; i++) { int type = (int)rnd(0, 1); if (type == 0) { - int x = (int)rnd(0, n - 1); - int y = (int)rnd(0, n - 1); + int x = (int)rnd(1, n); + int y = (int)rnd(1, n); ll v = rnd(-5, 5); ops.push_back({0, x, 0, y, 0, v}); } else { - int x1 = (int)rnd(0, n - 1); - int x2 = (int)rnd(x1, n - 1); - int y1 = (int)rnd(0, n - 1); - int y2 = (int)rnd(y1, n - 1); + int x1 = (int)rnd(1, n); + int x2 = (int)rnd(x1, n); + int y1 = (int)rnd(1, n); + int y2 = (int)rnd(y1, n); ops.push_back({1, x1, x2, y1, y2, 0}); } } @@ -300,7 +298,7 @@ void test_seg2dc_random() { } st.prep(); - vector> a(n, vector(n, 0)); + vector> a(n + 1, vector(n + 1, 0)); for (auto &op : ops) { if (op.type == 0) { a[op.x1][op.y1] = op.val; diff --git a/tests/4-optimizations/test_flow_dinic.cpp b/tests/4-optimizations/test_flow_dinic.cpp index 01217ff..94f5d4c 100644 --- a/tests/4-optimizations/test_flow_dinic.cpp +++ b/tests/4-optimizations/test_flow_dinic.cpp @@ -104,8 +104,8 @@ lr_res brute_lr(int n, int s, int t, const vector void t_dinic() { { dinic mf(2); - mf.add_edge(0, 1, 3); - assert(mf.max_flow(0, 1) == 3); + mf.add_edge(1, 2, 3); + assert(mf.max_flow(1, 2) == 3); } for (int it = 0; it < 200; it++) { int n = rnd(2, 10); @@ -118,12 +118,12 @@ void t_dinic() { int u = rnd(0, n - 1), v = rnd(0, n - 1); if (u == v) continue; ll cap = rnd(0, 7); - mf.add_edge(u, v, cap); + mf.add_edge(u + 1, v + 1, cap); na.add_edge(u, v, cap); } ll exp = na.max_flow(s, t); ll lim = rnd(0, 10); - assert(mf.max_flow(s, t, lim) == min(exp, lim)); + assert(mf.max_flow(s + 1, t + 1, lim) == min(exp, lim)); } } @@ -142,10 +142,10 @@ void t_lr_dinic() { int lo = rnd(0, 2); int hi = lo + rnd(0, 2); es.push_back({u, v, lo, hi, 0}); - f.add_edge(u, v, lo, hi); + f.add_edge(u + 1, v + 1, lo, hi); } auto exp = brute_lr(n, s, t, es); - auto got = f.max_flow(s, t); + auto got = f.max_flow(s + 1, t + 1); assert(got.fr == exp.ok); if (exp.ok) assert(got.sc == exp.flow); } diff --git a/tests/4-optimizations/test_flow_hk.cpp b/tests/4-optimizations/test_flow_hk.cpp index 4f289c4..6687b2f 100644 --- a/tests/4-optimizations/test_flow_hk.cpp +++ b/tests/4-optimizations/test_flow_hk.cpp @@ -32,7 +32,7 @@ void t_hk() { vector> g(n_l); for (int l = 0; l < n_l; l++) for (int r = 0; r < n_r; r++) - if (rnd(0, 1)) bm.add_edge(l, r), g[l].push_back(r); + if (rnd(0, 1)) bm.add_edge(l + 1, r + 1), g[l].push_back(r); assert(bm.max_matching() == brute_match(n_l, n_r, g)); } } diff --git a/tests/4-optimizations/test_flow_mcmf.cpp b/tests/4-optimizations/test_flow_mcmf.cpp index 08d0e60..3695bf4 100644 --- a/tests/4-optimizations/test_flow_mcmf.cpp +++ b/tests/4-optimizations/test_flow_mcmf.cpp @@ -132,14 +132,14 @@ void t_mcmf() { mcmf_spfa na; na.init(n); for (auto [u, v, cap, cost] : es) { - mf1.add_edge(u, v, cap, cost); - mf2.add_edge(u, v, cap, cost); + mf1.add_edge(u + 1, v + 1, cap, cost); + mf2.add_edge(u + 1, v + 1, cap, cost); na.add_edge(u, v, cap, cost); } ll max_f = rnd(0, 8); auto exp = na.min_cost_mf(s, t, max_f); - assert(mf1.min_cost_mf(s, t, max_f, true) == exp); - if (nonneg) assert(mf2.min_cost_mf(s, t, max_f, false) == exp); + assert(mf1.min_cost_mf(s + 1, t + 1, max_f, true) == exp); + if (nonneg) assert(mf2.min_cost_mf(s + 1, t + 1, max_f, false) == exp); } } @@ -159,10 +159,10 @@ void t_lr_mcmf() { int hi = lo + rnd(0, 2); int c = rnd(0, 5); es.push_back({u, v, lo, hi, c}); - f.add_edge(u, v, lo, hi, c); + f.add_edge(u + 1, v + 1, lo, hi, c); } auto exp = brute_lr(n, s, t, es); - auto got = f.max_flow(s, t, true); + auto got = f.max_flow(s + 1, t + 1, true); assert(got.fr == exp.ok); if (exp.ok) assert(got.sc.fr == exp.flow), assert(got.sc.sc == exp.cost); } diff --git a/tests/8-misc/test_diff_cons.cpp b/tests/8-misc/test_diff_cons.cpp index 92b138a..7c803f0 100644 --- a/tests/8-misc/test_diff_cons.cpp +++ b/tests/8-misc/test_diff_cons.cpp @@ -13,20 +13,20 @@ int rnd_int(int l, int r) { bool has_neg_cycle(int n, const vector> &edges) { const ll INF = (1LL << 60); - vector> d(n, vector(n, INF)); - for (int i = 0; i < n; i++) d[i][i] = 0; + vector> d(n + 1, vector(n + 1, INF)); + for (int i = 1; i <= n; i++) d[i][i] = 0; for (auto [u, v, w] : edges) d[u][v] = min(d[u][v], w); - for (int k = 0; k < n; k++) { - for (int i = 0; i < n; i++) { + for (int k = 1; k <= n; k++) { + for (int i = 1; i <= n; i++) { if (d[i][k] == INF) continue; - for (int j = 0; j < n; j++) { + for (int j = 1; j <= n; j++) { if (d[k][j] == INF) continue; ll nv = d[i][k] + d[k][j]; if (nv < d[i][j]) d[i][j] = nv; } } } - for (int i = 0; i < n; i++) + for (int i = 1; i <= n; i++) if (d[i][i] < 0) return true; return false; } @@ -38,8 +38,8 @@ void test_random() { diff_cons dc(n); vector> edges; for (int i = 0; i < m; i++) { - int u = rnd_int(0, n - 1); - int v = rnd_int(0, n - 1); + int u = rnd_int(1, n); + int v = rnd_int(1, n); ll w = rnd_int(-5, 5); dc.add_le(u, v, w); edges.push_back({u, v, w}); diff --git a/tests/8-misc/test_sqrt_mo.cpp b/tests/8-misc/test_sqrt_mo.cpp index 9641b26..fb670db 100644 --- a/tests/8-misc/test_sqrt_mo.cpp +++ b/tests/8-misc/test_sqrt_mo.cpp @@ -13,13 +13,13 @@ int rnd_int(int l, int r) { void test_distinct() { int n = 200, qn = 200; - vector a(n); - for (int i = 0; i < n; i++) a[i] = rnd_int(0, 30); + vector a(n + 1, 0); + for (int i = 1; i <= n; i++) a[i] = rnd_int(0, 30); vector qs(qn); for (int i = 0; i < qn; i++) { - int l = rnd_int(0, n - 1); - int r = rnd_int(l, n - 1); + int l = rnd_int(1, n); + int r = rnd_int(l, n); qs[i] = {l, r}; } From 682fc1c30f75a12d6b49ed2713b0469cbb7f5cd4 Mon Sep 17 00:00:00 2001 From: manoflearning <77jwk0724@gmail.com> Date: Tue, 6 Jan 2026 01:56:37 +0900 Subject: [PATCH 2/2] readme --- README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README.md b/README.md index 93b2ace..d60d191 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # CP Reference Codes My implementations of various data structures and algorithms for competitive programming. -## Indexing convention -- Default: **1-indexed** indices/vertices and **inclusive** ranges `[l, r]`. -- Exceptions: `src/5-string/*`, `src/1-ds/ds_pbds.cpp` are **0-indexed**; low-level pointer snippets (e.g. `src/8-misc/simd.cpp`) are 0-indexed. - ## Contents (GitHub links, `main`) - [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)