pub trait Monoid: SemiGroup + Unital {
// Provided methods
fn pow<E>(x: Self::T, exp: E) -> Self::T
where E: ExpBits { ... }
fn fold<I>(iter: I) -> Self::T
where I: IntoIterator<Item = Self::T> { ... }
}Expand description
associative binary operation and an identity element
Provided Methods§
Sourcefn pow<E>(x: Self::T, exp: E) -> Self::Twhere
E: ExpBits,
fn pow<E>(x: Self::T, exp: E) -> Self::Twhere
E: ExpBits,
binary exponentiation: $x^n = x\circ\ddots\circ x$
Examples found in repository?
More examples
crates/competitive/src/string/rolling_hash.rs (line 521)
517 fn muln_add(&mut self, x: &R::T, y: &R::T, n: usize) -> R::T {
518 if let Some(pow) = self.pow.get(n) {
519 R::add(&R::mul(x, pow), y)
520 } else {
521 let pow = <R::Multiplicative as Monoid>::pow(self.base.clone(), n);
522 R::add(&R::mul(x, &pow), y)
523 }
524 }
525 fn muln_sub(&mut self, l: &R::T, r: &R::T, n: usize) -> R::T {
526 if let Some(pow) = self.pow.get(n) {
527 R::sub(r, &R::mul(l, pow))
528 } else {
529 let pow = <R::Multiplicative as Monoid>::pow(self.base.clone(), n);
530 R::sub(r, &R::mul(l, &pow))
531 }
532 }crates/competitive/src/math/floor_sum.rs (line 259)
241fn floor_monoid_product<M>(
242 mut x: M::T,
243 mut y: M::T,
244 mut n: u64,
245 mut a: u64,
246 mut b: u64,
247 mut m: u64,
248) -> M::T
249where
250 M: Monoid,
251{
252 let mut c = (a * n + b) / m;
253 let mut pre = M::unit();
254 let mut suf = M::unit();
255 loop {
256 let (p, q) = (a / m, b / m);
257 a %= m;
258 b %= m;
259 x = M::operate(&x, &M::pow(y.clone(), p));
260 pre = M::operate(&pre, &M::pow(y.clone(), q));
261 c -= p * n + q;
262 if c == 0 {
263 break;
264 }
265 let d = (m * c - b - 1) / a + 1;
266 suf = M::operate(&y, &M::operate(&M::pow(x.clone(), n - d), &suf));
267 b = m - b - 1 + a;
268 n = c - 1;
269 c = d;
270 swap(&mut m, &mut a);
271 swap(&mut x, &mut y);
272 }
273 x = M::pow(x.clone(), n);
274 M::operate(&M::operate(&pre, &x), &suf)
275}crates/competitive/src/algorithm/baby_step_giant_step.rs (line 19)
5pub fn baby_step_giant_step<M>(x: M::T, y: M::T, n: usize) -> Option<usize>
6where
7 M: Monoid<T: Eq + Hash>,
8{
9 if M::is_unit(&y) {
10 return Some(0);
11 }
12 let block_size = 1usize.max((n as f64).sqrt() as _);
13 let mut baby = HashSet::new();
14 let mut t = y.clone();
15 for _ in 0..block_size {
16 t = M::operate(&x, &t);
17 baby.insert(t.clone());
18 }
19 let g = M::pow(x.clone(), block_size);
20 let mut t = M::unit();
21 let mut fail = 0usize;
22 for k in (0..n).step_by(block_size) {
23 let nt = M::operate(&g, &t);
24 if baby.contains(&nt) {
25 for m in k..n.min(k + block_size) {
26 if t == y {
27 return Some(m);
28 }
29 t = M::operate(&x, &t);
30 }
31 fail += 1;
32 if fail >= 2 {
33 break;
34 }
35 }
36 t = nt;
37 }
38 None
39}fn fold<I>(iter: I) -> Self::Twhere
I: IntoIterator<Item = Self::T>,
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.