From 12d8d8805c56a684778f6e2af76a3253750a95f2 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Mon, 13 Jun 2022 13:22:24 +0900 Subject: [PATCH 01/10] Implement Zero, One, and Pow --- Cargo.toml | 1 + src/modint.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 463b124..4408768 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +num-traits = { version = "0.2.11", optional = true } [dev-dependencies] input = { path = "./crates/input" } diff --git a/src/modint.rs b/src/modint.rs index 8aa5220..21507d2 100644 --- a/src/modint.rs +++ b/src/modint.rs @@ -898,6 +898,39 @@ macro_rules! impl_basic_traits { } } + #[cfg(feature = "num-traits")] + impl<$generic_param: $generic_param_bound> num_traits::Zero for $self { + #[inline] + fn zero() -> Self { + Self::new(0) + } + #[inline] + fn is_zero(&self) -> bool { + self == &Self::zero() + } + } + + #[cfg(feature = "num-traits")] + impl<$generic_param: $generic_param_bound> num_traits::One for $self { + #[inline] + fn one() -> Self { + Self::new(1) + } + #[inline] + fn is_one(&self) -> bool { + self == &Self::one() + } + } + + #[cfg(feature = "num-traits")] + impl<$generic_param: $generic_param_bound> num_traits::Pow for $self { + type Output=$self; + #[inline] + fn pow(self, rhs: u64) -> Self::Output { + self.pow(rhs) + } + } + impl_basic_traits!($($rest)*); }; } 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 02/10] 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 03/10] 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 9034a0db9069a29a378b3a1e6cd14a80fa2e137a Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Thu, 16 Jun 2022 12:05:51 +0900 Subject: [PATCH 04/10] Impl Zero & One for all num_traits counterparts --- src/num_traits.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/num_traits.rs b/src/num_traits.rs index 5fa6a23..36d3b56 100644 --- a/src/num_traits.rs +++ b/src/num_traits.rs @@ -3,22 +3,36 @@ pub trait Zero { /// The additive identity element. fn zero() -> Self; } +#[cfg(feature = "num-traits")] +impl Zero for T { + fn zero() -> Self { + num_traits::Zero::zero() + } +} /// A type that has a multiplicative identity element. pub trait One { /// The multiplicative identity element. fn one() -> Self; } +#[cfg(feature = "num-traits")] +impl One for T { + fn one() -> Self { + num_traits::One::one() + } +} macro_rules! impl_zero { ($zero: literal, $one: literal: $($t: ty),*) => { $( + #[cfg(not(feature="num-traits"))] impl Zero for $t { fn zero() -> Self { $zero } } + #[cfg(not(feature="num-traits"))] impl One for $t { fn one() -> Self { $one @@ -31,11 +45,13 @@ 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); +#[cfg(not(feature = "num-traits"))] impl Zero for core::num::Wrapping { fn zero() -> Self { Self(T::zero()) } } +#[cfg(not(feature = "num-traits"))] impl One for core::num::Wrapping { fn one() -> Self { Self(T::one()) From ef261ae26d2648cb4a4bec810140871051484847 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Fri, 17 Jun 2022 01:30:42 +0900 Subject: [PATCH 05/10] impl Zero and One for modint --- src/modint.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/modint.rs b/src/modint.rs index 21507d2..5dcbcc8 100644 --- a/src/modint.rs +++ b/src/modint.rs @@ -910,6 +910,14 @@ macro_rules! impl_basic_traits { } } + #[cfg(not(feature = "num-traits"))] + impl<$generic_param: $generic_param_bound> $crate::num_traits::Zero for $self { + #[inline] + fn zero() -> Self { + Self::new(0) + } + } + #[cfg(feature = "num-traits")] impl<$generic_param: $generic_param_bound> num_traits::One for $self { #[inline] @@ -922,6 +930,14 @@ macro_rules! impl_basic_traits { } } + #[cfg(not(feature = "num-traits"))] + impl<$generic_param: $generic_param_bound> $crate::num_traits::One for $self { + #[inline] + fn one() -> Self { + Self::new(1) + } + } + #[cfg(feature = "num-traits")] impl<$generic_param: $generic_param_bound> num_traits::Pow for $self { type Output=$self; From fd5ce0b676dcfd54b96654310bb9f866bf22025d Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Wed, 29 Mar 2023 17:24:46 +0200 Subject: [PATCH 06/10] Bump num-traits version to 0.2.15 for [AtCoder 2023/1 Language Update](https://docs.google.com/spreadsheets/d/1HXyOXt5bKwhKWXruzUvfMFHQtBxfZQ0047W7VVObnXI/edit#gid=408033513&range=I2). --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 7b98f10..69d9103 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -num-traits = { version = "0.2.11", optional = true } +num-traits = { version = "0.2.15", optional = true } [dev-dependencies] proconio = "=0.3.6" From 69c3cf2b31ce01f9cd77deaf10d0ca3dde1364e5 Mon Sep 17 00:00:00 2001 From: Mizar Date: Mon, 27 Mar 2023 22:37:40 +0900 Subject: [PATCH 07/10] 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 08/10] 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 From 1c0c3fe15065739d5265d7785886dfc8374368a2 Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Sat, 15 Apr 2023 23:02:01 +0200 Subject: [PATCH 09/10] Move KaTeX-in-doc configs to Cargo.toml --- .cargo/config.toml | 8 -------- Cargo.toml | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 .cargo/config.toml diff --git a/.cargo/config.toml b/.cargo/config.toml deleted file mode 100644 index 3d99f63..0000000 --- a/.cargo/config.toml +++ /dev/null @@ -1,8 +0,0 @@ -[build] -# This works both on local `cargo doc` and on docs.rs because we don't have any `normal` dependency. -# In most cases, `package.metadata.docs.rs` is recommended. -# -# See also: -# - https://docs.rs/rustdoc-katex-demo -# - https://docs.rs/rust-latex-doc-minimal-example -rustdocflags = ["--html-in-header", "./doc/katex-header.html"] diff --git a/Cargo.toml b/Cargo.toml index b6dcbfa..70ff13a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ keywords = ["competitive"] categories = ["algorithms", "data-structures"] [package.metadata.docs.rs] +all-features = true rustdoc-args = ["--html-in-header", "./doc/katex-header.html"] [lib] From fa6e8e992fd30a8cf196977ae37ee46c763b515e Mon Sep 17 00:00:00 2001 From: TonalidadeHidrica <47710717+TonalidadeHidrica@users.noreply.github.com> Date: Sat, 15 Apr 2023 23:15:05 +0200 Subject: [PATCH 10/10] Fix expand.py so that modint depends on num_traits --- expand.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expand.py b/expand.py index 8f04fc2..57c6789 100755 --- a/expand.py +++ b/expand.py @@ -42,7 +42,7 @@ 'math': ('internal_math',), 'maxflow': ('internal_type_traits', 'internal_queue',), 'mincostflow': ('internal_type_traits',), - 'modint': ('internal_math',), + 'modint': ('internal_math', 'num_traits',), 'scc': ('internal_scc',), 'segtree': ('internal_bit', 'internal_type_traits',), 'twosat': ('internal_scc',),