From 0f0aa8ba3fa9cd0100f1a0d5e8c93bca741b6295 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Fri, 17 Jun 2022 00:57:39 +0900 Subject: [PATCH 1/5] Move Zero and One to public module --- src/internal_type_traits.rs | 30 ++------------------------ src/lib.rs | 2 ++ src/num_traits.rs | 43 +++++++++++++++++++++++++++++++++++++ src/segtree.rs | 3 ++- 4 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 src/num_traits.rs diff --git a/src/internal_type_traits.rs b/src/internal_type_traits.rs index 88a52a9..9b00aec 100644 --- a/src/internal_type_traits.rs +++ b/src/internal_type_traits.rs @@ -52,25 +52,13 @@ pub trait Integral: + fmt::Debug + fmt::Binary + fmt::Octal - + Zero - + One + + crate::num_traits::Zero + + crate::num_traits::One + BoundedBelow + BoundedAbove { } -/// Class that has additive identity element -pub trait Zero { - /// The additive identity element - fn zero() -> Self; -} - -/// Class that has multiplicative identity element -pub trait One { - /// The multiplicative identity element - fn one() -> Self; -} - pub trait BoundedBelow { fn min_value() -> Self; } @@ -82,20 +70,6 @@ pub trait BoundedAbove { macro_rules! impl_integral { ($($ty:ty),*) => { $( - impl Zero for $ty { - #[inline] - fn zero() -> Self { - 0 - } - } - - impl One for $ty { - #[inline] - fn one() -> Self { - 1 - } - } - impl BoundedBelow for $ty { #[inline] fn min_value() -> Self { diff --git a/src/lib.rs b/src/lib.rs index 5452b25..3040bcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,8 @@ pub mod segtree; pub mod string; pub mod twosat; +pub mod num_traits; + pub(crate) mod internal_bit; pub(crate) mod internal_math; pub(crate) mod internal_queue; diff --git a/src/num_traits.rs b/src/num_traits.rs new file mode 100644 index 0000000..5fa6a23 --- /dev/null +++ b/src/num_traits.rs @@ -0,0 +1,43 @@ +/// A type that has an additive identity element. +pub trait Zero { + /// The additive identity element. + fn zero() -> Self; +} + +/// A type that has a multiplicative identity element. +pub trait One { + /// The multiplicative identity element. + fn one() -> Self; +} + +macro_rules! impl_zero { + ($zero: literal, $one: literal: $($t: ty),*) => { + $( + impl Zero for $t { + fn zero() -> Self { + $zero + } + } + + impl One for $t { + fn one() -> Self { + $one + } + } + )* + }; +} +impl_zero!(0, 1: usize, u8, u16, u32, u64, u128); +impl_zero!(0, 1: isize, i8, i16, i32, i64, i128); +impl_zero!(0.0, 1.0: f32, f64); + +impl Zero for core::num::Wrapping { + fn zero() -> Self { + Self(T::zero()) + } +} +impl One for core::num::Wrapping { + fn one() -> Self { + Self(T::one()) + } +} diff --git a/src/segtree.rs b/src/segtree.rs index b543aa3..01ee9e7 100644 --- a/src/segtree.rs +++ b/src/segtree.rs @@ -1,5 +1,6 @@ use crate::internal_bit::ceil_pow2; -use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero}; +use crate::internal_type_traits::{BoundedAbove, BoundedBelow}; +use crate::num_traits::{One, Zero}; use std::cmp::{max, min}; use std::convert::Infallible; use std::marker::PhantomData; From e919319791dd45d064515ee8e00310362d52f240 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Fri, 17 Jun 2022 01:00:01 +0900 Subject: [PATCH 2/5] Use Zero trait in fenwick tree --- examples/library-checker-static-range-sum.rs | 2 +- src/fenwicktree.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/library-checker-static-range-sum.rs b/examples/library-checker-static-range-sum.rs index a4a5d8b..ee64011 100644 --- a/examples/library-checker-static-range-sum.rs +++ b/examples/library-checker-static-range-sum.rs @@ -15,7 +15,7 @@ fn main() { lrs: [(usize, usize); q], } - let mut fenwick = FenwickTree::new(n, 0); + let mut fenwick = FenwickTree::::new(n); for (i, a) in r#as.into_iter().enumerate() { fenwick.add(i, a); } diff --git a/src/fenwicktree.rs b/src/fenwicktree.rs index 9256ff0..b4270e6 100644 --- a/src/fenwicktree.rs +++ b/src/fenwicktree.rs @@ -1,20 +1,20 @@ +use crate::num_traits::Zero; + // Reference: https://en.wikipedia.org/wiki/Fenwick_tree pub struct FenwickTree { n: usize, ary: Vec, - e: T, } -impl> FenwickTree { - pub fn new(n: usize, e: T) -> Self { +impl + Zero> FenwickTree { + pub fn new(n: usize) -> Self { FenwickTree { n, - ary: vec![e.clone(); n], - e, + ary: vec![T::zero(); n], } } pub fn accum(&self, mut idx: usize) -> T { - let mut sum = self.e.clone(); + let mut sum = T::zero(); while idx > 0 { sum += self.ary[idx - 1].clone(); idx &= idx - 1; @@ -48,7 +48,7 @@ mod tests { #[test] fn fenwick_tree_works() { - let mut bit = FenwickTree::new(5, 0i64); + let mut bit = FenwickTree::::new(5); // [1, 2, 3, 4, 5] for i in 0..5 { bit.add(i, i as i64 + 1); From ed246d1c73568f3c1aa442d060be68549699e889 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Thu, 16 Jun 2022 19:41:07 +0900 Subject: [PATCH 3/5] FenwickTree no longer needs Clone; it adds refs --- src/fenwicktree.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/fenwicktree.rs b/src/fenwicktree.rs index b4270e6..b0cca6a 100644 --- a/src/fenwicktree.rs +++ b/src/fenwicktree.rs @@ -1,3 +1,5 @@ +use std::iter::repeat_with; + use crate::num_traits::Zero; // Reference: https://en.wikipedia.org/wiki/Fenwick_tree @@ -6,30 +8,30 @@ pub struct FenwickTree { ary: Vec, } -impl + Zero> FenwickTree { +impl std::ops::AddAssign<&'a T> + Zero> FenwickTree { pub fn new(n: usize) -> Self { FenwickTree { n, - ary: vec![T::zero(); n], + ary: repeat_with(T::zero).take(n).collect(), } } pub fn accum(&self, mut idx: usize) -> T { let mut sum = T::zero(); while idx > 0 { - sum += self.ary[idx - 1].clone(); + sum += &self.ary[idx - 1]; idx &= idx - 1; } sum } /// performs data[idx] += val; - pub fn add(&mut self, mut idx: usize, val: U) + pub fn add(&mut self, mut idx: usize, val: U) where - T: std::ops::AddAssign, + T: for<'a> std::ops::AddAssign<&'a U>, { let n = self.n; idx += 1; while idx <= n { - self.ary[idx - 1] += val.clone(); + self.ary[idx - 1] += &val; idx += idx & idx.wrapping_neg(); } } From 69c3cf2b31ce01f9cd77deaf10d0ca3dde1364e5 Mon Sep 17 00:00:00 2001 From: Mizar Date: Mon, 27 Mar 2023 22:37:40 +0900 Subject: [PATCH 4/5] expand: fenwicktree depends internal_type_traits --- expand.py | 1 + 1 file changed, 1 insertion(+) diff --git a/expand.py b/expand.py index 283d6fb..45c9c41 100755 --- a/expand.py +++ b/expand.py @@ -37,6 +37,7 @@ 'internal_bit', 'internal_math', 'internal_queue', 'internal_scc', 'internal_type_traits',) dependency_list = {'convolution': ('internal_bit', 'modint',), + 'fenwicktree': ('internal_type_traits',), 'lazysegtree': ('internal_bit', 'segtree'), 'math': ('internal_math',), 'maxflow': ('internal_type_traits', 'internal_queue',), From 142bd16416aff0cecac4213ad33cb807caf008a1 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Wed, 29 Mar 2023 19:32:33 +0200 Subject: [PATCH 5/5] Correct dependencies descibed in expand.py --- expand.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/expand.py b/expand.py index 45c9c41..8f04fc2 100755 --- a/expand.py +++ b/expand.py @@ -32,12 +32,12 @@ output_header = '//https://github.com/rust-lang-ja/ac-library-rs\n' opt_list = ['help', 'all', 'output='] output_list_all = ('convolution', 'dsu', 'fenwicktree', 'lazysegtree', 'math', - 'maxflow', 'mincostflow', 'modint', 'scc', 'segtree', - 'string', 'twosat', + 'maxflow', 'mincostflow', 'modint', 'num_traits', 'scc', + 'segtree', 'string', 'twosat', 'internal_bit', 'internal_math', 'internal_queue', 'internal_scc', 'internal_type_traits',) dependency_list = {'convolution': ('internal_bit', 'modint',), - 'fenwicktree': ('internal_type_traits',), + 'fenwicktree': ('num_traits',), 'lazysegtree': ('internal_bit', 'segtree'), 'math': ('internal_math',), 'maxflow': ('internal_type_traits', 'internal_queue',), @@ -45,7 +45,8 @@ 'modint': ('internal_math',), 'scc': ('internal_scc',), 'segtree': ('internal_bit', 'internal_type_traits',), - 'twosat': ('internal_scc',), } + 'twosat': ('internal_scc',), + 'internal_type_traits': ('num_traits',), } src_path = 'src/' output_path = None