From 776c4a8483c0c34a76749a94d619274fda319a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=9BThiagoFBastos?= Date: Mon, 6 Apr 2026 21:37:46 -0300 Subject: [PATCH 1/2] chore: add test pipeline --- .github/workflows/ci.yml | 39 +++ .../src/data_structures/fenwick_tree.rs | 80 +++--- .../src/data_structures/mod.rs | 4 +- .../data_structures/recursive_segment_tree.rs | 239 +++++++++--------- .../src/data_structures/segment_tree.rs | 156 ++++++------ .../src/data_structures/union_find.rs | 107 ++++---- competitive_programming/src/graphs/mod.rs | 2 +- .../src/graphs/tree_diameter.rs | 78 +++--- competitive_programming/src/lib.rs | 4 +- competitive_programming/src/math/mod.rs | 2 +- .../src/math/mod_number.rs | 29 +-- .../src/math/number_theory/gcd_subsets.rs | 86 +++---- .../src/math/number_theory/miller_rabin.rs | 88 +++---- .../src/math/number_theory/mod.rs | 2 +- competitive_programming/src/string/kmp.rs | 41 ++- .../src/string/manacher.rs | 8 +- competitive_programming/src/string/mod.rs | 2 +- .../src/string/z_function.rs | 40 +-- .../tests/data_structures/fenwick_tree.rs | 19 +- .../tests/data_structures/mod.rs | 4 +- .../data_structures/recursive_segment_tree.rs | 15 +- .../tests/data_structures/segment_tree.rs | 28 +- .../tests/data_structures/union_find.rs | 7 +- competitive_programming/tests/graphs/mod.rs | 2 +- .../tests/graphs/tree_diameter.rs | 10 +- competitive_programming/tests/math/mod.rs | 2 +- .../tests/math/mod_number.rs | 5 +- .../tests/math/number_theory/gcd_subsets.rs | 5 +- .../tests/math/number_theory/miller_rabin.rs | 4 +- .../tests/math/number_theory/mod.rs | 2 +- competitive_programming/tests/string/kmp.rs | 2 - .../tests/string/manacher.rs | 6 +- competitive_programming/tests/string/mod.rs | 2 +- .../tests/string/z_function.rs | 1 - competitive_programming/tests/test.rs | 4 +- 35 files changed, 567 insertions(+), 558 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0a895ad --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: Rust CI + +on: + push: + branches: + - '**' + pull_request: + +jobs: + build-test-lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout do código + uses: actions/checkout@v4 + + - name: Instalar Rust + uses: dtolnay/rust-toolchain@stable + with: + components: clippy, rustfmt + + - name: Cache de dependências + uses: Swatinem/rust-cache@v2 + + - name: Check de formatação (rustfmt) + working-directory: competitive_programming + run: cargo fmt --all -- --check + + - name: Lint (clippy) + working-directory: competitive_programming + run: cargo clippy --all-targets --all-features -- -D warnings + + - name: Build + working-directory: competitive_programming + run: cargo build --all-targets + + - name: Rodar testes + working-directory: competitive_programming + run: cargo test --all \ No newline at end of file diff --git a/competitive_programming/src/data_structures/fenwick_tree.rs b/competitive_programming/src/data_structures/fenwick_tree.rs index 31805ca..4d1884b 100644 --- a/competitive_programming/src/data_structures/fenwick_tree.rs +++ b/competitive_programming/src/data_structures/fenwick_tree.rs @@ -5,63 +5,59 @@ */ pub trait Constants { - - fn initial() -> Self; // the initial constant + fn initial() -> Self; // the initial constant } #[derive(Clone)] pub struct FenwickTree { - data: Vec, // the fenwick tree data - length: usize, // the number of elements of the fenwick tree - op: OP // the binary operator to apply an operation in the fenwick tree + data: Vec, // the fenwick tree data + length: usize, // the number of elements of the fenwick tree + op: OP, // the binary operator to apply an operation in the fenwick tree } impl T> FenwickTree { - /** * create a new instance of FenwickTree * @param length the number of elements of the Fenwick Tree * @param op the binary function that handles with operations * @return the new instance of FenwickTree */ - pub fn new(length: usize, op: OP) -> Self { - - Self { - data: vec![T::initial(); length + 1], - length, - op - } - } - - /** - * find the result of an operation of first k elements - * @param k the number of the first elements for which we want to find the result - */ - pub fn query(&self, mut k: i32) -> T { - let mut result = T::initial(); - - assert!(k <= self.length as i32); + pub fn new(length: usize, op: OP) -> Self { + Self { + data: vec![T::initial(); length + 1], + length, + op, + } + } - while k > 0 { - result = (self.op)(result, self.data[k as usize]); - k -= k & -k; - } + /** + * find the result of an operation of first k elements + * @param k the number of the first elements for which we want to find the result + */ + pub fn query(&self, mut k: i32) -> T { + let mut result = T::initial(); - result - } + assert!(k <= self.length as i32); - /** - * update a value to the element at position k - * @param k the position for which we want to modify - * @param value the value for which we want to apply - */ - pub fn update(&mut self, mut k: i32, value: T) { + while k > 0 { + result = (self.op)(result, self.data[k as usize]); + k -= k & -k; + } - assert!(k > 0); + result + } - while k <= self.length as i32 { - self.data[k as usize] = (self.op)(self.data[k as usize], value); - k += k & -k; - } - } -} \ No newline at end of file + /** + * update a value to the element at position k + * @param k the position for which we want to modify + * @param value the value for which we want to apply + */ + pub fn update(&mut self, mut k: i32, value: T) { + assert!(k > 0); + + while k <= self.length as i32 { + self.data[k as usize] = (self.op)(self.data[k as usize], value); + k += k & -k; + } + } +} diff --git a/competitive_programming/src/data_structures/mod.rs b/competitive_programming/src/data_structures/mod.rs index ba82ca5..d341d4f 100644 --- a/competitive_programming/src/data_structures/mod.rs +++ b/competitive_programming/src/data_structures/mod.rs @@ -1,4 +1,4 @@ -pub mod segment_tree; pub mod fenwick_tree; +pub mod recursive_segment_tree; +pub mod segment_tree; pub mod union_find; -pub mod recursive_segment_tree; \ No newline at end of file diff --git a/competitive_programming/src/data_structures/recursive_segment_tree.rs b/competitive_programming/src/data_structures/recursive_segment_tree.rs index ff87935..e0388b3 100644 --- a/competitive_programming/src/data_structures/recursive_segment_tree.rs +++ b/competitive_programming/src/data_structures/recursive_segment_tree.rs @@ -4,123 +4,128 @@ * Description: Simple recursive segment tree agnostic to operations. */ -pub struct SegTree where OP: Fn(T, T) -> T { - data: Vec, // the segment tree data - size: usize, // the number of elements - op: OP // the binary operator +pub struct SegTree +where + OP: Fn(T, T) -> T, +{ + data: Vec, // the segment tree data + size: usize, // the number of elements + op: OP, // the binary operator } -impl SegTree where OP: Fn(T, T) -> T { - - /** - * Create a new instance of SegTree - * @param values the initial array of elements - * @param op the binary operator - */ - pub fn new(values: &[T], op: OP) -> Self { - let n = values.len(); - - let mut st = Self { - data: vec![T::default(); 4 * n], - size: n, - op - }; - - st.build(values, 0, n - 1, 1); - - return st; - } - - /** - * Build the segment tree - * @param values the initial array of elements - * @param lo the leftmost position of the current range node - * @param hi the rightmost position of the current range node - * @param p the current node - */ - fn build(&mut self, values: &[T], lo: usize, hi: usize, p: usize) { - if lo == hi { - self.data[p] = values[lo]; - return; - } - - let mid = (lo + hi) / 2; - - self.build(values, lo, mid, 2 * p); - self.build(values, mid + 1, hi, 2 * p + 1); - - self.data[p] = (self.op)(self.data[2 * p], self.data[2 * p + 1]); - } - - /** - * Update the value at a specific position - * @param k the position to update - * @param value the value that will replace the old one - * @param lo the leftmost position of the current range node - * @param hi the rightmost position of the current range node - * @param p the current node - */ - fn change(&mut self, k: usize, value: T, lo: usize, hi: usize, p: usize) { - if lo == hi { - self.data[p] = value; - return; - } - - let mid = (lo + hi) / 2; - - if k <= mid { - self.change(k, value, lo, mid, 2 * p); - } else { - self.change(k, value, mid + 1, hi, 2 * p + 1); - } - - self.data[p] = (self.op)(self.data[2 * p], self.data[2 * p + 1]); - } - - /** - * Find the value of an operation over a range - * @param l the leftmost position of the target range - * @param r the rightmost position of the target range - * @param lo the leftmost position of the current range node - * @param hi the rightmost position of the current range node - * @param p the current node - */ - fn answer(&self, l: usize, r: usize, lo: usize, hi: usize, p: usize) -> T { - if lo >= l && hi <= r { - return self.data[p]; - } - - let mid = (lo + hi) / 2; - - if r <= mid { - return self.answer(l, r, lo, mid, 2 * p); - } else if l > mid { - return self.answer(l, r, mid + 1, hi, 2 * p + 1); - } - - let res1 = self.answer(l, r, lo, mid, 2 * p); - let res2 = self.answer(l, r, mid + 1, hi, 2 * p + 1); - - return (self.op)(res1, res2); - } - - /** - * Update the value at a specific position - * @param k the position to update - * @param value the value that will replace the old one - */ - pub fn update(&mut self, k: usize, value: T) { - assert!(k < self.size); - self.change(k, value, 0, self.size - 1, 1); - } - - /** - * Find the value of an operation over a range - * @param l the leftmost position of the target range - * @param r the rightmost position of the target range - */ - pub fn query(&self, l: usize, r: usize) -> T { - assert!(l <= r && r < self.size); - return self.answer(l, r, 0, self.size - 1, 1); - } +impl SegTree +where + OP: Fn(T, T) -> T, +{ + /** + * Create a new instance of SegTree + * @param values the initial array of elements + * @param op the binary operator + */ + pub fn new(values: &[T], op: OP) -> Self { + let n = values.len(); + + let mut st = Self { + data: vec![T::default(); 4 * n], + size: n, + op, + }; + + st.build(values, 0, n - 1, 1); + + st + } + + /** + * Build the segment tree + * @param values the initial array of elements + * @param lo the leftmost position of the current range node + * @param hi the rightmost position of the current range node + * @param p the current node + */ + fn build(&mut self, values: &[T], lo: usize, hi: usize, p: usize) { + if lo == hi { + self.data[p] = values[lo]; + return; + } + + let mid = (lo + hi) / 2; + + self.build(values, lo, mid, 2 * p); + self.build(values, mid + 1, hi, 2 * p + 1); + + self.data[p] = (self.op)(self.data[2 * p], self.data[2 * p + 1]); + } + + /** + * Update the value at a specific position + * @param k the position to update + * @param value the value that will replace the old one + * @param lo the leftmost position of the current range node + * @param hi the rightmost position of the current range node + * @param p the current node + */ + fn change(&mut self, k: usize, value: T, lo: usize, hi: usize, p: usize) { + if lo == hi { + self.data[p] = value; + return; + } + + let mid = (lo + hi) / 2; + + if k <= mid { + self.change(k, value, lo, mid, 2 * p); + } else { + self.change(k, value, mid + 1, hi, 2 * p + 1); + } + + self.data[p] = (self.op)(self.data[2 * p], self.data[2 * p + 1]); + } + + /** + * Find the value of an operation over a range + * @param l the leftmost position of the target range + * @param r the rightmost position of the target range + * @param lo the leftmost position of the current range node + * @param hi the rightmost position of the current range node + * @param p the current node + */ + fn answer(&self, l: usize, r: usize, lo: usize, hi: usize, p: usize) -> T { + if lo >= l && hi <= r { + return self.data[p]; + } + + let mid = (lo + hi) / 2; + + if r <= mid { + return self.answer(l, r, lo, mid, 2 * p); + } else if l > mid { + return self.answer(l, r, mid + 1, hi, 2 * p + 1); + } + + let res1 = self.answer(l, r, lo, mid, 2 * p); + let res2 = self.answer(l, r, mid + 1, hi, 2 * p + 1); + + (self.op)(res1, res2) + } + + /** + * Update the value at a specific position + * @param k the position to update + * @param value the value that will replace the old one + */ + pub fn update(&mut self, k: usize, value: T) { + assert!(k < self.size); + self.change(k, value, 0, self.size - 1, 1); + } + + /** + * Find the value of an operation over a range + * @param l the leftmost position of the target range + * @param r the rightmost position of the target range + */ + pub fn query(&self, l: usize, r: usize) -> T { + assert!(l <= r && r < self.size); + self.answer(l, r, 0, self.size - 1, 1) + } } diff --git a/competitive_programming/src/data_structures/segment_tree.rs b/competitive_programming/src/data_structures/segment_tree.rs index 61d110f..4ebafe9 100644 --- a/competitive_programming/src/data_structures/segment_tree.rs +++ b/competitive_programming/src/data_structures/segment_tree.rs @@ -6,92 +6,92 @@ // Trait for initial value pub trait Constants { - fn initial() -> Self; + fn initial() -> Self; } #[derive(Clone)] -pub struct SegTree where OP: Fn(T, T) -> T { - data: Vec, // the segment tree data - length: usize, // the number of elements - op: OP // the binary operator +pub struct SegTree +where + OP: Fn(T, T) -> T, +{ + data: Vec, // the segment tree data + length: usize, // the number of elements + op: OP, // the binary operator } -impl SegTree where OP: Fn(T, T) -> T { - +impl SegTree +where + OP: Fn(T, T) -> T, +{ /** * Create a new instance of SegTree * @param values the initial array * @param op the binary operator to calculate the values */ - pub fn new(values: &[T], op: OP) -> Self { - - let n = values.len(); - let mut data = vec![T::initial(); 2 * n]; - - for i in n..2*n { - data[i] = values[i - n]; - } - - for i in (1..n).rev() { - data[i] = op(data[i << 1], data[(i << 1) | 1]); - } - - Self { - data, - length: n, - op: op - } - } - - /** - * Find the answer of query between l and r - * @param l the leftmost position of the interval - * @param r the rightmost position of the interval - * @return the query answer of the values inside of the interval [l, r] - */ - pub fn query(&self, mut l: usize, mut r: usize) -> T { - let mut answer = T::initial(); - - assert!(l <= r && r < self.length); - - l += self.length; - r += self.length; - - while l <= r { - - if l & 1 == 1 { - answer = (self.op)(answer, self.data[l]); - l += 1; - } - - if r & 1 == 0 { - answer = (self.op)(answer, self.data[r]); - r -= 1; - } - - l >>= 1; - r >>= 1; - } - - answer - } - - /** - * Update a position to replacing the old value by the new one - * @param k the position to change the value - * @param value the value that will be replaced at position k - */ - pub fn update(&mut self, mut k: usize, value: T) { - - assert!(k < self.length); - - k += self.length; - - self.data[k] = value; - - while k > 1 { - k >>= 1; - self.data[k] = (self.op)(self.data[k << 1], self.data[(k << 1) | 1]); - } - } + pub fn new(values: &[T], op: OP) -> Self { + let n = values.len(); + let mut data = vec![T::initial(); 2 * n]; + + data[n..(2 * n)].copy_from_slice(&values[..n]); + + for i in (1..n).rev() { + data[i] = op(data[i << 1], data[(i << 1) | 1]); + } + + Self { + data, + length: n, + op, + } + } + + /** + * Find the answer of query between l and r + * @param l the leftmost position of the interval + * @param r the rightmost position of the interval + * @return the query answer of the values inside of the interval [l, r] + */ + pub fn query(&self, mut l: usize, mut r: usize) -> T { + let mut answer = T::initial(); + + assert!(l <= r && r < self.length); + + l += self.length; + r += self.length; + + while l <= r { + if l & 1 == 1 { + answer = (self.op)(answer, self.data[l]); + l += 1; + } + + if r & 1 == 0 { + answer = (self.op)(answer, self.data[r]); + r -= 1; + } + + l >>= 1; + r >>= 1; + } + + answer + } + + /** + * Update a position to replacing the old value by the new one + * @param k the position to change the value + * @param value the value that will be replaced at position k + */ + pub fn update(&mut self, mut k: usize, value: T) { + assert!(k < self.length); + + k += self.length; + + self.data[k] = value; + + while k > 1 { + k >>= 1; + self.data[k] = (self.op)(self.data[k << 1], self.data[(k << 1) | 1]); + } + } } diff --git a/competitive_programming/src/data_structures/union_find.rs b/competitive_programming/src/data_structures/union_find.rs index 6cdd631..6dc7de7 100644 --- a/competitive_programming/src/data_structures/union_find.rs +++ b/competitive_programming/src/data_structures/union_find.rs @@ -8,67 +8,68 @@ Simple Disjoint Set/Union Find with rank and path compression */ pub struct DisjointSet { - parent: Vec, // the parent of each vertex - rank: Vec // the rank of the disjoint set + parent: Vec, // the parent of each vertex + rank: Vec, // the rank of the disjoint set } impl DisjointSet { - /** - * create a new instance of DisjointSet - * @param n number of vertexes - * @return a DisjointSet - */ - pub fn new(n: usize) -> Self { + /** + * create a new instance of DisjointSet + * @param n number of vertexes + * @return a DisjointSet + */ + pub fn new(n: usize) -> Self { + Self { + parent: (0..n).collect(), + rank: vec![0; n], + } + } - Self { - parent: (0..n).collect(), - rank: vec![0; n] - } - } + /** + * find the root of disjoint set that u belongs + * @param u a vertex of the disjoint set that you want to find the root + * @return the root of disjoint set + */ + pub fn find_set(&mut self, u: usize) -> usize { + if u == self.parent[u] { + return u; + } - /** - * find the root of disjoint set that u belongs - * @param u a vertex of the disjoint set that you want to find the root - * @return the root of disjoint set - */ - pub fn find_set(&mut self, u: usize) -> usize { - - if u == self.parent[u] { - return u; - } + self.parent[u] = self.find_set(self.parent[u]); - self.parent[u] = self.find_set(self.parent[u]); + self.parent[u] + } - return self.parent[u]; - } + /** + * join the connected components that u and v belongs + * @param u a vertex of one connected component + * @param v a vertex of other connected component + */ + pub fn unite(&mut self, mut u: usize, mut v: usize) { + u = self.find_set(u); + v = self.find_set(v); - /** - * join the connected components that u and v belongs - * @param u a vertex of one connected component - * @param v a vertex of other connected component - */ - pub fn unite(&mut self, mut u: usize, mut v: usize) { + if u == v { + return; + } else if self.rank[u] > self.rank[v] { + std::mem::swap(&mut u, &mut v); + } - u = self.find_set(u); - v = self.find_set(v); + self.parent[u] = v; + self.rank[v] = if self.rank[u] == self.rank[v] { + self.rank[v] + 1 + } else { + self.rank[v] + }; + } - if u == v { - return; - } else if self.rank[u] > self.rank[v] { - std::mem::swap(&mut u, &mut v); - } - - self.parent[u] = v; - self.rank[v] = if self.rank[u] == self.rank[v] { self.rank[v] + 1 } else { self.rank[v] }; - } - - /** - * Return if two vertexes belongs to the same connected component - * @param u a vertex of one connected component - * @param v a vertex of one connected component - * @return true if u and v belongs to the same connected component and false otherwise - */ - pub fn same(&mut self, u: usize, v: usize) -> bool { - return self.find_set(u) == self.find_set(v); - } + /** + * Return if two vertexes belongs to the same connected component + * @param u a vertex of one connected component + * @param v a vertex of one connected component + * @return true if u and v belongs to the same connected component and false otherwise + */ + pub fn same(&mut self, u: usize, v: usize) -> bool { + self.find_set(u) == self.find_set(v) + } } diff --git a/competitive_programming/src/graphs/mod.rs b/competitive_programming/src/graphs/mod.rs index c6fca78..f41b751 100644 --- a/competitive_programming/src/graphs/mod.rs +++ b/competitive_programming/src/graphs/mod.rs @@ -1 +1 @@ -pub mod tree_diameter; \ No newline at end of file +pub mod tree_diameter; diff --git a/competitive_programming/src/graphs/tree_diameter.rs b/competitive_programming/src/graphs/tree_diameter.rs index 40da6c2..e2e2b77 100644 --- a/competitive_programming/src/graphs/tree_diameter.rs +++ b/competitive_programming/src/graphs/tree_diameter.rs @@ -4,43 +4,43 @@ * Description: Given a tree, the algorithm below finds the diameter of the tree. */ - use std::collections::VecDeque; - - /** - * find the diameter of a given tree - * @param adj the adjacency list of the tree - * @return the diameter - */ -pub fn diameter(adj: &Vec>) -> usize { - let n = adj.len(); - - let mut deg = vec![0; n]; - let mut dist = vec![0; n]; - let mut queue = VecDeque::new(); - - for i in 0..n { - deg[i] = adj[i].len(); - - if deg[i] == 1 { - queue.push_back(i); - } - } - - while !queue.is_empty() { - let src = queue.pop_front().unwrap(); - - for &dest in adj[src].iter() { - deg[dest] -= 1; - - if deg[dest] == 1 { - dist[dest] = 1 + dist[src]; - queue.push_back(dest); - } - } - } - - let &d = dist.iter().max().unwrap(); - let count = dist.iter().filter(|&&x| x == d).count(); - - return 2 * d + count - 1; +use std::collections::VecDeque; + +/** + * find the diameter of a given tree + * @param adj the adjacency list of the tree + * @return the diameter + */ +pub fn diameter(adj: &[Vec]) -> usize { + let n = adj.len(); + + let mut deg = vec![0; n]; + let mut dist = vec![0; n]; + let mut queue = VecDeque::new(); + + for i in 0..n { + deg[i] = adj[i].len(); + + if deg[i] == 1 { + queue.push_back(i); + } + } + + while !queue.is_empty() { + let src = queue.pop_front().unwrap(); + + for &dest in adj[src].iter() { + deg[dest] -= 1; + + if deg[dest] == 1 { + dist[dest] = 1 + dist[src]; + queue.push_back(dest); + } + } + } + + let &d = dist.iter().max().unwrap(); + let count = dist.iter().filter(|&&x| x == d).count(); + + 2 * d + count - 1 } diff --git a/competitive_programming/src/lib.rs b/competitive_programming/src/lib.rs index 0cf355f..515da57 100644 --- a/competitive_programming/src/lib.rs +++ b/competitive_programming/src/lib.rs @@ -1,4 +1,4 @@ -pub mod math; pub mod data_structures; +pub mod graphs; +pub mod math; pub mod string; -pub mod graphs; \ No newline at end of file diff --git a/competitive_programming/src/math/mod.rs b/competitive_programming/src/math/mod.rs index f4b4b03..a4a30f5 100644 --- a/competitive_programming/src/math/mod.rs +++ b/competitive_programming/src/math/mod.rs @@ -1,4 +1,4 @@ mod mod_number; pub mod number_theory; -pub use mod_number::{ModNumber}; \ No newline at end of file +pub use mod_number::ModNumber; diff --git a/competitive_programming/src/math/mod_number.rs b/competitive_programming/src/math/mod_number.rs index 1594487..e66b5c2 100644 --- a/competitive_programming/src/math/mod_number.rs +++ b/competitive_programming/src/math/mod_number.rs @@ -8,11 +8,10 @@ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssi #[derive(Clone, Copy, PartialEq, Eq)] pub struct ModNumber { - number: i64 // number (mod MOD) + number: i64, // number (mod MOD) } impl ModNumber { - /** * Create a new instance of ModNumber * @param initial the value that will be stored @@ -30,9 +29,7 @@ impl ModNumber { initial += MOD; } - Self { - number: initial - } + Self { number: initial } } /** @@ -44,15 +41,14 @@ impl ModNumber { /** * Return the stored number raised to the power of n - */ + */ pub fn pow(&self, mut n: u64) -> Self { let mut result = Self::new(1); - let mut number = self.clone(); + let mut number = *self; while n > 0 { - if n & 1 == 1 { - result = result * number; + result *= number; } number = number * number; @@ -94,23 +90,24 @@ impl Sub for ModNumber { } } -// operator * +// operator * impl Mul for ModNumber { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { - let result = self.number.checked_mul(rhs.number); if result.is_none() { - return ModNumber::new(((self.number as i128 * rhs.number as i128) % MOD as i128) as i64); + return ModNumber::new( + ((self.number as i128 * rhs.number as i128) % MOD as i128) as i64, + ); } ModNumber::new(result.unwrap() % MOD) } } -// operator / +// operator / impl Div for ModNumber { type Output = Self; @@ -136,15 +133,13 @@ impl Neg for ModNumber { // operator += impl AddAssign for ModNumber { - fn add_assign(&mut self, rhs: Self) { *self = *self + rhs; } } // operator -= -impl SubAssign for ModNumber { - +impl SubAssign for ModNumber { fn sub_assign(&mut self, rhs: Self) { *self = *self - rhs; } @@ -152,7 +147,6 @@ impl SubAssign for ModNumber { // operator *= impl MulAssign for ModNumber { - fn mul_assign(&mut self, rhs: Self) { *self = *self * rhs; } @@ -160,7 +154,6 @@ impl MulAssign for ModNumber { // operator /= impl DivAssign for ModNumber { - fn div_assign(&mut self, rhs: Self) { *self = *self / rhs; } diff --git a/competitive_programming/src/math/number_theory/gcd_subsets.rs b/competitive_programming/src/math/number_theory/gcd_subsets.rs index b8c41e6..a1d54ca 100644 --- a/competitive_programming/src/math/number_theory/gcd_subsets.rs +++ b/competitive_programming/src/math/number_theory/gcd_subsets.rs @@ -5,48 +5,48 @@ * finds the count of non-empty subsets whose gcd is equal to k for each k = 1, ..., n. */ - /** - * find de count of subsets that are equal to k = 1, ..., n - * @param values the array with numbers, being that 1 <= values_i <= n - */ +/** + * find de count of subsets that are equal to k = 1, ..., n + * @param values the array with numbers, being that 1 <= values_i <= n + */ pub fn count_gcd_subsets(values: &[i32]) -> Vec { - let n = values.len(); - - let mut dp = vec![0; n + 1]; - let mut pow = vec![0; n + 1]; - let mut frequency = vec![0; n + 1]; - - assert!(*values.iter().min().unwrap() >= 0); - - for value in values.iter() { - frequency[*value as usize] += 1; - } - - pow[0] = 1; - for i in 1..=n { - pow[i] = pow[i - 1] << 1; - if pow[i] >= MOD { - pow[i] -= MOD; - } - } - - for i in 1..=n { - for j in (i..=n).step_by(i) { - dp[i] += frequency[j] as i64; - } - dp[i] = (pow[dp[i] as usize] - 1 + MOD) % MOD; - } - - for i in (1..=n).rev() { - for j in (2*i..=n).step_by(i) { - dp[i] -= dp[j]; - if dp[i] < 0 { - dp[i] += MOD; - } - } - } - - dp.remove(0); - - return dp; + let n = values.len(); + + let mut dp = vec![0; n + 1]; + let mut pow = vec![0; n + 1]; + let mut frequency = vec![0; n + 1]; + + assert!(*values.iter().min().unwrap() >= 0); + + for value in values.iter() { + frequency[*value as usize] += 1; + } + + pow[0] = 1; + for i in 1..=n { + pow[i] = pow[i - 1] << 1; + if pow[i] >= MOD { + pow[i] -= MOD; + } + } + + for i in 1..=n { + for j in (i..=n).step_by(i) { + dp[i] += frequency[j] as i64; + } + dp[i] = (pow[dp[i] as usize] - 1 + MOD) % MOD; + } + + for i in (1..=n).rev() { + for j in (2 * i..=n).step_by(i) { + dp[i] -= dp[j]; + if dp[i] < 0 { + dp[i] += MOD; + } + } + } + + dp.remove(0); + + dp } diff --git a/competitive_programming/src/math/number_theory/miller_rabin.rs b/competitive_programming/src/math/number_theory/miller_rabin.rs index 602cf95..5a96e7f 100644 --- a/competitive_programming/src/math/number_theory/miller_rabin.rs +++ b/competitive_programming/src/math/number_theory/miller_rabin.rs @@ -6,69 +6,69 @@ * @return n^p mod m */ fn bin_exp(n: i128, p: i128, m: i128) -> i128 { - if p == 0 { - return 1; - } + if p == 0 { + return 1; + } - let mut res = bin_exp(n, p >> 1, m); + let mut res = bin_exp(n, p >> 1, m); - res = res * res % m; + res = res * res % m; - if p & 1 == 1 { - res = res * n % m; - } + if p & 1 == 1 { + res = res * n % m; + } - return res; + res } /** - * Miller-Rabin algorithm to check primes + * Miller-Rabin algorithm to check primes * @param n the number to check if is prime or not * @return a boolean that is true if n is prime and false otherwise */ pub fn is_prime(n: i64) -> bool { - let primes: [i64; 9] = [2, 3, 5, 7, 11, 13, 17, 19, 23]; + let primes: [i64; 9] = [2, 3, 5, 7, 11, 13, 17, 19, 23]; - for &p in primes.iter() { - if n % p == 0 { - return n == p; - } - } + for &p in primes.iter() { + if n % p == 0 { + return n == p; + } + } - if n < *primes.last().unwrap() { - return false; - } + if n < *primes.last().unwrap() { + return false; + } - let mut t = n - 1; - let mut s = 0; + let mut t = n - 1; + let mut s = 0; - while t & 1 == 0 { - t >>= 1; - s += 1; - } + while t & 1 == 0 { + t >>= 1; + s += 1; + } - for &p in primes.iter() { - let mut pow = bin_exp(p as i128, t as i128, n as i128); + for &p in primes.iter() { + let mut pow = bin_exp(p as i128, t as i128, n as i128); - if pow == 1 { - continue; - } + if pow == 1 { + continue; + } - let mut ok = false; + let mut ok = false; - for _ in 0..s { - if pow == n as i128 - 1 { - ok = true; - break; - } + for _ in 0..s { + if pow == n as i128 - 1 { + ok = true; + break; + } - pow = pow * pow % n as i128; - } + pow = pow * pow % n as i128; + } - if !ok { - return false; - } - } + if !ok { + return false; + } + } - return true; -} \ No newline at end of file + true +} diff --git a/competitive_programming/src/math/number_theory/mod.rs b/competitive_programming/src/math/number_theory/mod.rs index f91e9e1..2289d1d 100644 --- a/competitive_programming/src/math/number_theory/mod.rs +++ b/competitive_programming/src/math/number_theory/mod.rs @@ -2,4 +2,4 @@ mod gcd_subsets; mod miller_rabin; pub use gcd_subsets::count_gcd_subsets; -pub use miller_rabin::is_prime; \ No newline at end of file +pub use miller_rabin::is_prime; diff --git a/competitive_programming/src/string/kmp.rs b/competitive_programming/src/string/kmp.rs index 6c0e630..4226296 100644 --- a/competitive_programming/src/string/kmp.rs +++ b/competitive_programming/src/string/kmp.rs @@ -4,32 +4,31 @@ * Description: The function below implements the KMP algorithm for a given string. */ - /** - * KMP algorithm for strings - * @param str the target string - * @return an array containing the result of KMP algorithm - */ -pub fn kmp(str: &String) -> Vec { - - let chars = str.chars().collect::>(); +/** + * KMP algorithm for strings + * @param str the target string + * @return an array containing the result of KMP algorithm + */ +pub fn kmp(str: &str) -> Vec { + let chars = str.chars().collect::>(); - let mut kmp = Vec::with_capacity(str.len()); + let mut kmp = Vec::with_capacity(str.len()); - kmp.push(0); + kmp.push(0); - for i in 1..chars.len() { - let mut k = kmp[i - 1]; + for i in 1..chars.len() { + let mut k = kmp[i - 1]; - while k > 0 && chars[k] != chars[i] { - k = kmp[k - 1]; - } + while k > 0 && chars[k] != chars[i] { + k = kmp[k - 1]; + } - if chars[k] == chars[i] { - k += 1; - } + if chars[k] == chars[i] { + k += 1; + } - kmp.push(k); - } + kmp.push(k); + } - kmp + kmp } diff --git a/competitive_programming/src/string/manacher.rs b/competitive_programming/src/string/manacher.rs index b17bda7..69a2f0a 100644 --- a/competitive_programming/src/string/manacher.rs +++ b/competitive_programming/src/string/manacher.rs @@ -9,7 +9,7 @@ * @param s the target string * @return the size of the largest palindrome substring */ -pub fn manacher(s: &String) -> usize { +pub fn manacher(s: &str) -> usize { let n = s.len(); let str = s.chars().collect::>(); @@ -21,7 +21,6 @@ pub fn manacher(s: &String) -> usize { let mut len = 0; for i in 0..n { - if i as i32 <= r { d1[i] = d1[l + r as usize - i].min(r as usize + 1 - i); d2[i] = d2[l + r as usize + 1 - i].min(r as usize + 1 - i); @@ -31,7 +30,7 @@ pub fn manacher(s: &String) -> usize { d1[i] += 1; } - while i + d2[i] < n && i >= d2[i] + 1 && str[i - d2[i] - 1] == str[i + d2[i]] { + while i + d2[i] < n && i > d2[i] && str[i - d2[i] - 1] == str[i + d2[i]] { d2[i] += 1; } @@ -45,9 +44,8 @@ pub fn manacher(s: &String) -> usize { r = i as i32 + d1[i] as i32 - 1; } - len = len.max(r as usize + 1 - l); } len -} \ No newline at end of file +} diff --git a/competitive_programming/src/string/mod.rs b/competitive_programming/src/string/mod.rs index ed7c565..d5de51a 100644 --- a/competitive_programming/src/string/mod.rs +++ b/competitive_programming/src/string/mod.rs @@ -1,3 +1,3 @@ pub mod kmp; +pub mod manacher; pub mod z_function; -pub mod manacher; \ No newline at end of file diff --git a/competitive_programming/src/string/z_function.rs b/competitive_programming/src/string/z_function.rs index 1f76ec2..d486abb 100644 --- a/competitive_programming/src/string/z_function.rs +++ b/competitive_programming/src/string/z_function.rs @@ -9,28 +9,28 @@ * @param s the target string * @return a vector with the results of z-function */ -pub fn z_function(s: &String) -> Vec { - let n = s.len(); - let str = s.chars().collect::>(); - let mut z = vec![0; n]; +pub fn z_function(s: &str) -> Vec { + let n = s.len(); + let str = s.chars().collect::>(); + let mut z = vec![0; n]; - let mut l = 0; - let mut r = 0; + let mut l = 0; + let mut r = 0; - for i in 1..n { - if i <= r { - z[i] = z[i - l].min(r - i + 1); - } + for i in 1..n { + if i <= r { + z[i] = z[i - l].min(r - i + 1); + } - while i + z[i] < n && str[z[i]] == str[i + z[i]] { - z[i] += 1; - } + while i + z[i] < n && str[z[i]] == str[i + z[i]] { + z[i] += 1; + } - if i + z[i] - 1 > r { - l = i; - r = i + z[i] - 1; - } - } + if i + z[i] - 1 > r { + l = i; + r = i + z[i] - 1; + } + } - return z; -} \ No newline at end of file + z +} diff --git a/competitive_programming/tests/data_structures/fenwick_tree.rs b/competitive_programming/tests/data_structures/fenwick_tree.rs index 79409ec..0629467 100644 --- a/competitive_programming/tests/data_structures/fenwick_tree.rs +++ b/competitive_programming/tests/data_structures/fenwick_tree.rs @@ -11,13 +11,11 @@ mod fenwick_tree_tests { impl Constants for Int32 { fn initial() -> Self { - return Int32(0); + Int32(0) } } - let sum = |a: Int32, b: Int32| { - return Int32(a.0 + b.0); - }; + let sum = |a: Int32, b: Int32| Int32(a.0 + b.0); let mut ft = FenwickTree::new(N, sum); @@ -28,7 +26,10 @@ mod fenwick_tree_tests { for i in 1..=N { for j in i..=N { let sum = (i + j) * (j - i + 1) / 2; - assert_eq!(Int32(ft.query(j as i32).0 - ft.query(i as i32 - 1).0), Int32(sum as i32)); + assert_eq!( + Int32(ft.query(j as i32).0 - ft.query(i as i32 - 1).0), + Int32(sum as i32) + ); } } } @@ -42,13 +43,11 @@ mod fenwick_tree_tests { impl Constants for Int32 { fn initial() -> Self { - return Int32(i32::MIN); + Int32(i32::MIN) } } - let max = |a: Int32, b: Int32| { - return Int32(a.0.max(b.0)); - }; + let max = |a: Int32, b: Int32| Int32(a.0.max(b.0)); let mut ft = FenwickTree::new(N, max); @@ -60,4 +59,4 @@ mod fenwick_tree_tests { assert_eq!(ft.query(i as i32), Int32(i as i32)); } } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/data_structures/mod.rs b/competitive_programming/tests/data_structures/mod.rs index ba82ca5..d341d4f 100644 --- a/competitive_programming/tests/data_structures/mod.rs +++ b/competitive_programming/tests/data_structures/mod.rs @@ -1,4 +1,4 @@ -pub mod segment_tree; pub mod fenwick_tree; +pub mod recursive_segment_tree; +pub mod segment_tree; pub mod union_find; -pub mod recursive_segment_tree; \ No newline at end of file diff --git a/competitive_programming/tests/data_structures/recursive_segment_tree.rs b/competitive_programming/tests/data_structures/recursive_segment_tree.rs index cef7dba..09101a6 100644 --- a/competitive_programming/tests/data_structures/recursive_segment_tree.rs +++ b/competitive_programming/tests/data_structures/recursive_segment_tree.rs @@ -1,14 +1,10 @@ - #[cfg(test)] mod segment_tree_tests { use competitive_programming::data_structures::recursive_segment_tree::*; #[test] fn test_min_value_in_interval() { - - let operation = |a: i32, b: i32| { - a.min(b) - }; + let operation = |a: i32, b: i32| a.min(b); let values = [1, 2, 3, -1, 4, 5]; @@ -28,10 +24,7 @@ mod segment_tree_tests { #[test] fn test_sum_values_in_interval() { - - let operation = |a, b| { - a + b - }; + let operation = |a, b| a + b; let values = [9, 1, 4, 3, 5]; @@ -45,6 +38,6 @@ mod segment_tree_tests { assert_eq!(st.query(0, 1), 10); assert_eq!(st.query(2, 3), -6); - assert_eq!(st.query(2, 4), -1); + assert_eq!(st.query(2, 4), -1); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/data_structures/segment_tree.rs b/competitive_programming/tests/data_structures/segment_tree.rs index 687a41a..a4ca2db 100644 --- a/competitive_programming/tests/data_structures/segment_tree.rs +++ b/competitive_programming/tests/data_structures/segment_tree.rs @@ -1,25 +1,24 @@ - #[cfg(test)] mod segment_tree_tests { use competitive_programming::data_structures::segment_tree::*; #[test] fn test_min_value_in_interval() { - #[derive(Clone, Copy, PartialEq, PartialOrd, Debug)] struct Int32(i32); impl Constants for Int32 { fn initial() -> Self { - return Int32(i32::MAX); + Int32(i32::MAX) } } - let operation = |a: Int32, b: Int32| { - Int32(a.0.min(b.0)) - }; + let operation = |a: Int32, b: Int32| Int32(a.0.min(b.0)); - let values = [1, 2, 3, -1, 4, 5].iter().map(|value| Int32(*value)).collect::>(); + let values = [1, 2, 3, -1, 4, 5] + .iter() + .map(|value| Int32(*value)) + .collect::>(); let mut st = SegTree::new(&values, operation); @@ -42,15 +41,16 @@ mod segment_tree_tests { impl Constants for Int32 { fn initial() -> Self { - return Int32(0); + Int32(0) } } - let operation = |a: Int32, b: Int32| { - Int32(a.0 + b.0) - }; + let operation = |a: Int32, b: Int32| Int32(a.0 + b.0); - let values = [9, 1, 4, 3, 5].iter().map(|value| Int32(*value)).collect::>(); + let values = [9, 1, 4, 3, 5] + .iter() + .map(|value| Int32(*value)) + .collect::>(); let mut st = SegTree::new(&values, operation); @@ -62,6 +62,6 @@ mod segment_tree_tests { assert_eq!(st.query(0, 1), Int32(10)); assert_eq!(st.query(2, 3), Int32(-6)); - assert_eq!(st.query(2, 4), Int32(-1)); + assert_eq!(st.query(2, 4), Int32(-1)); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/data_structures/union_find.rs b/competitive_programming/tests/data_structures/union_find.rs index 6b9a555..b44d942 100644 --- a/competitive_programming/tests/data_structures/union_find.rs +++ b/competitive_programming/tests/data_structures/union_find.rs @@ -1,4 +1,3 @@ - #[cfg(test)] mod union_find_tests { use competitive_programming::data_structures::union_find::*; @@ -28,7 +27,7 @@ mod union_find_tests { } for i in 0..N { - for j in i+1..N { + for j in i + 1..N { assert!(uf.same(i, j)); } } @@ -41,14 +40,14 @@ mod union_find_tests { let mut uf = DisjointSet::new(N); for k in 0..2 { - for i in (k+2..N).step_by(2) { + for i in (k + 2..N).step_by(2) { assert!(!uf.same(k, i)); uf.unite(k, i); } } for i in 0..N { - for j in i+1..N { + for j in i + 1..N { let same_parity = i % 2 == j % 2; assert_eq!(uf.same(i, j), same_parity); } diff --git a/competitive_programming/tests/graphs/mod.rs b/competitive_programming/tests/graphs/mod.rs index c6fca78..f41b751 100644 --- a/competitive_programming/tests/graphs/mod.rs +++ b/competitive_programming/tests/graphs/mod.rs @@ -1 +1 @@ -pub mod tree_diameter; \ No newline at end of file +pub mod tree_diameter; diff --git a/competitive_programming/tests/graphs/tree_diameter.rs b/competitive_programming/tests/graphs/tree_diameter.rs index 3df8a96..d0bee73 100644 --- a/competitive_programming/tests/graphs/tree_diameter.rs +++ b/competitive_programming/tests/graphs/tree_diameter.rs @@ -1,16 +1,14 @@ - #[cfg(test)] mod tree_diameter_tests { use competitive_programming::graphs::tree_diameter::diameter; - fn add_edge(adj: &mut Vec>, u: usize, v: usize) { + fn add_edge(adj: &mut [Vec], u: usize, v: usize) { adj[u].push(v); adj[v].push(u); } #[test] - fn test_small_tree() - { + fn test_small_tree() { const N: usize = 5; let mut adj = vec![vec![]; N]; @@ -41,7 +39,7 @@ mod tree_diameter_tests { #[test] fn test_trivial_tree() { - const N: usize = 1; + const N: usize = 1; let adj: Vec> = vec![vec![]; N]; @@ -70,4 +68,4 @@ mod tree_diameter_tests { assert_eq!(diam, 6); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/math/mod.rs b/competitive_programming/tests/math/mod.rs index fc70dc4..5f11fd0 100644 --- a/competitive_programming/tests/math/mod.rs +++ b/competitive_programming/tests/math/mod.rs @@ -1,2 +1,2 @@ pub mod mod_number; -pub mod number_theory; \ No newline at end of file +pub mod number_theory; diff --git a/competitive_programming/tests/math/mod_number.rs b/competitive_programming/tests/math/mod_number.rs index 9bbfafb..edfdecf 100644 --- a/competitive_programming/tests/math/mod_number.rs +++ b/competitive_programming/tests/math/mod_number.rs @@ -1,4 +1,3 @@ - #[cfg(test)] mod mod_number_tests { use competitive_programming::math::ModNumber; @@ -21,7 +20,7 @@ mod mod_number_tests { assert_eq!(number.value(), 0); } - #[test] + #[test] fn test_constructor_with_large_negative() { const MOD: i64 = 1_000_000_007; @@ -189,4 +188,4 @@ mod mod_number_tests { assert!(num1 != num2); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/math/number_theory/gcd_subsets.rs b/competitive_programming/tests/math/number_theory/gcd_subsets.rs index cd671ae..59ffac5 100644 --- a/competitive_programming/tests/math/number_theory/gcd_subsets.rs +++ b/competitive_programming/tests/math/number_theory/gcd_subsets.rs @@ -1,10 +1,7 @@ - - #[cfg(test)] mod gcd_subsets_tests { use competitive_programming::math::number_theory::count_gcd_subsets; - #[test] fn test_case_1() { const MOD: i64 = 1_000_000_007; @@ -40,4 +37,4 @@ mod gcd_subsets_tests { assert_eq!(result, expected); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/math/number_theory/miller_rabin.rs b/competitive_programming/tests/math/number_theory/miller_rabin.rs index 391cb02..c71358e 100644 --- a/competitive_programming/tests/math/number_theory/miller_rabin.rs +++ b/competitive_programming/tests/math/number_theory/miller_rabin.rs @@ -1,5 +1,3 @@ - - #[cfg(test)] mod miller_rabin_tests { use competitive_programming::math::number_theory::is_prime; @@ -47,4 +45,4 @@ mod miller_rabin_tests { // muito grande (~5.7e17) assert!(!is_prime(576_460_752_303_423_488i64)); } -} \ No newline at end of file +} diff --git a/competitive_programming/tests/math/number_theory/mod.rs b/competitive_programming/tests/math/number_theory/mod.rs index 402e21b..dc8426c 100644 --- a/competitive_programming/tests/math/number_theory/mod.rs +++ b/competitive_programming/tests/math/number_theory/mod.rs @@ -1,2 +1,2 @@ pub mod gcd_subsets; -pub mod miller_rabin; \ No newline at end of file +pub mod miller_rabin; diff --git a/competitive_programming/tests/string/kmp.rs b/competitive_programming/tests/string/kmp.rs index ee1bd94..beee635 100644 --- a/competitive_programming/tests/string/kmp.rs +++ b/competitive_programming/tests/string/kmp.rs @@ -1,4 +1,3 @@ - #[cfg(test)] mod kmp_tests { @@ -6,7 +5,6 @@ mod kmp_tests { #[test] fn test_simple_match() { - let s = String::from("abc"); let t = String::from("xyzabc"); diff --git a/competitive_programming/tests/string/manacher.rs b/competitive_programming/tests/string/manacher.rs index 3a3c974..0889ac3 100644 --- a/competitive_programming/tests/string/manacher.rs +++ b/competitive_programming/tests/string/manacher.rs @@ -1,4 +1,3 @@ - #[cfg(test)] mod manacher_tests { use competitive_programming::string::manacher::*; @@ -84,7 +83,6 @@ mod manacher_tests { assert_eq!(len, 7); } - #[test] fn test_cses_sample_test_case_6() { let str = String::from("aaccaabbaaccaaccaabbaaccaa"); @@ -128,5 +126,5 @@ mod manacher_tests { let len = manacher(&str); assert_eq!(len, str.len()); - } -} \ No newline at end of file + } +} diff --git a/competitive_programming/tests/string/mod.rs b/competitive_programming/tests/string/mod.rs index ed7c565..d5de51a 100644 --- a/competitive_programming/tests/string/mod.rs +++ b/competitive_programming/tests/string/mod.rs @@ -1,3 +1,3 @@ pub mod kmp; +pub mod manacher; pub mod z_function; -pub mod manacher; \ No newline at end of file diff --git a/competitive_programming/tests/string/z_function.rs b/competitive_programming/tests/string/z_function.rs index c1212dc..475fda3 100644 --- a/competitive_programming/tests/string/z_function.rs +++ b/competitive_programming/tests/string/z_function.rs @@ -1,4 +1,3 @@ - #[cfg(test)] mod z_function_tests { use competitive_programming::string::z_function::*; diff --git a/competitive_programming/tests/test.rs b/competitive_programming/tests/test.rs index bb4a996..a637941 100644 --- a/competitive_programming/tests/test.rs +++ b/competitive_programming/tests/test.rs @@ -1,4 +1,4 @@ -mod math; mod data_structures; +mod graphs; +mod math; mod string; -mod graphs; \ No newline at end of file From 3be36b5d44ba415b34e90cac584f405ae4b979b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=9BThiagoFBastos?= Date: Tue, 7 Apr 2026 06:30:13 -0300 Subject: [PATCH 2/2] refactor: change the path of some modules --- competitive_programming/src/data_structures/mod.rs | 4 +++- competitive_programming/src/graphs/mod.rs | 4 +++- competitive_programming/src/string/mod.rs | 10 +++++++--- .../tests/data_structures/union_find.rs | 2 +- competitive_programming/tests/graphs/tree_diameter.rs | 2 +- competitive_programming/tests/string/kmp.rs | 2 +- competitive_programming/tests/string/manacher.rs | 2 +- competitive_programming/tests/string/z_function.rs | 2 +- 8 files changed, 18 insertions(+), 10 deletions(-) diff --git a/competitive_programming/src/data_structures/mod.rs b/competitive_programming/src/data_structures/mod.rs index d341d4f..1ba2b38 100644 --- a/competitive_programming/src/data_structures/mod.rs +++ b/competitive_programming/src/data_structures/mod.rs @@ -1,4 +1,6 @@ pub mod fenwick_tree; pub mod recursive_segment_tree; pub mod segment_tree; -pub mod union_find; +mod union_find; + +pub use union_find::DisjointSet; diff --git a/competitive_programming/src/graphs/mod.rs b/competitive_programming/src/graphs/mod.rs index f41b751..abc9905 100644 --- a/competitive_programming/src/graphs/mod.rs +++ b/competitive_programming/src/graphs/mod.rs @@ -1 +1,3 @@ -pub mod tree_diameter; +mod tree_diameter; + +pub use tree_diameter::diameter; diff --git a/competitive_programming/src/string/mod.rs b/competitive_programming/src/string/mod.rs index d5de51a..5e8f4e0 100644 --- a/competitive_programming/src/string/mod.rs +++ b/competitive_programming/src/string/mod.rs @@ -1,3 +1,7 @@ -pub mod kmp; -pub mod manacher; -pub mod z_function; +mod kmp; +mod manacher; +mod z_function; + +pub use kmp::kmp; +pub use manacher::manacher; +pub use z_function::z_function; diff --git a/competitive_programming/tests/data_structures/union_find.rs b/competitive_programming/tests/data_structures/union_find.rs index b44d942..8eb05a4 100644 --- a/competitive_programming/tests/data_structures/union_find.rs +++ b/competitive_programming/tests/data_structures/union_find.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod union_find_tests { - use competitive_programming::data_structures::union_find::*; + use competitive_programming::data_structures::DisjointSet; #[test] fn test_tree_star() { diff --git a/competitive_programming/tests/graphs/tree_diameter.rs b/competitive_programming/tests/graphs/tree_diameter.rs index d0bee73..3f4bf9f 100644 --- a/competitive_programming/tests/graphs/tree_diameter.rs +++ b/competitive_programming/tests/graphs/tree_diameter.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tree_diameter_tests { - use competitive_programming::graphs::tree_diameter::diameter; + use competitive_programming::graphs::diameter; fn add_edge(adj: &mut [Vec], u: usize, v: usize) { adj[u].push(v); diff --git a/competitive_programming/tests/string/kmp.rs b/competitive_programming/tests/string/kmp.rs index beee635..ae1627f 100644 --- a/competitive_programming/tests/string/kmp.rs +++ b/competitive_programming/tests/string/kmp.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod kmp_tests { - use competitive_programming::string::kmp::kmp; + use competitive_programming::string::kmp; #[test] fn test_simple_match() { diff --git a/competitive_programming/tests/string/manacher.rs b/competitive_programming/tests/string/manacher.rs index 0889ac3..a68c652 100644 --- a/competitive_programming/tests/string/manacher.rs +++ b/competitive_programming/tests/string/manacher.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod manacher_tests { - use competitive_programming::string::manacher::*; + use competitive_programming::string::manacher; #[test] fn test_yosupo_sample_test_case_1() { diff --git a/competitive_programming/tests/string/z_function.rs b/competitive_programming/tests/string/z_function.rs index 475fda3..8e21c4d 100644 --- a/competitive_programming/tests/string/z_function.rs +++ b/competitive_programming/tests/string/z_function.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod z_function_tests { - use competitive_programming::string::z_function::*; + use competitive_programming::string::z_function; #[test] fn test_yosupo_sample_test_case_1() {