Skip to main content

Magma

Trait Magma 

Source
pub trait Magma {
    type T: Clone;

    // Required method
    fn operate(x: &Self::T, y: &Self::T) -> Self::T;

    // Provided methods
    fn reverse_operate(x: &Self::T, y: &Self::T) -> Self::T { ... }
    fn operate_assign(x: &mut Self::T, y: &Self::T) { ... }
}
Expand description

binary operaion: $T \circ T \to T$

Required Associated Types§

Source

type T: Clone

type of operands: $T$

Required Methods§

Source

fn operate(x: &Self::T, y: &Self::T) -> Self::T

binary operaion: $\circ$

Provided Methods§

Source

fn reverse_operate(x: &Self::T, y: &Self::T) -> Self::T

Source

fn operate_assign(x: &mut Self::T, y: &Self::T)

Examples found in repository?
crates/competitive/src/algebra/ring.rs (line 43)
42    fn add_assign(x: &mut Self::T, y: &Self::T) {
43        <Self::Additive as Magma>::operate_assign(x, y);
44    }
45
46    fn mul_assign(x: &mut Self::T, y: &Self::T) {
47        <Self::Multiplicative as Magma>::operate_assign(x, y);
48    }
More examples
Hide additional examples
crates/competitive/src/data_structure/binary_indexed_tree.rs (line 51)
46    pub fn from_slice(slice: &[M::T]) -> Self {
47        let n = slice.len();
48        let mut bit = vec![M::unit(); n + 1];
49        for (i, x) in slice.iter().enumerate() {
50            let k = i + 1;
51            M::operate_assign(&mut bit[k], x);
52            let j = k + (k & (!k + 1));
53            if j <= n {
54                bit[j] = M::operate(&bit[j], &bit[k]);
55            }
56        }
57        Self { n, bit }
58    }
crates/competitive/src/math/bitwiseand_convolve.rs (line 98)
89    pub fn push(&mut self, x: M::T) {
90        let i = self.data.len();
91        self.data.push(x);
92        let mut k = 0;
93        while i >> k & 1 == 1 {
94            let size = 1 << k;
95            let chunk = &mut self.data[i - (size * 2 - 1)..];
96            let (x, y) = chunk.split_at_mut(size);
97            for (x, y) in x.iter_mut().zip(y.iter()) {
98                M::operate_assign(x, y);
99            }
100            k += 1;
101        }
102    }
crates/competitive/src/algorithm/doubling.rs (line 155)
148    pub fn find_first(
149        &self,
150        pos: usize,
151        mut pred: impl FnMut(usize, &M::T) -> bool,
152    ) -> Option<(usize, (usize, M::T))> {
153        let (mut k, (mut pos, mut x)) = self.find_last(pos, |k, x| !pred(k, x));
154        k += 1;
155        M::operate_assign(&mut x, &self.table[pos].1);
156        pos = self.table[pos].0;
157        if pred(pos, &x) {
158            Some((k, (pos, x)))
159        } else {
160            None
161        }
162    }
crates/competitive/src/data_structure/transducer.rs (line 194)
183    pub fn step<S, I, B>(&mut self, mut sigma: S)
184    where
185        S: FnMut() -> I,
186        I: IntoIterator<Item = B>,
187        B: Borrow<T::Input>,
188    {
189        for (state, value) in self.dp.drain() {
190            for input in sigma() {
191                if let Some((nstate, _)) = self.fst.relation(&state, input.borrow()) {
192                    self.ndp
193                        .entry(nstate)
194                        .and_modify(|acc| M::operate_assign(acc, &value))
195                        .or_insert_with(|| value.clone());
196                }
197            }
198        }
199        swap(&mut self.dp, &mut self.ndp);
200        self.fst.stepout();
201    }
202    pub fn step_effect<S, I, B, F>(&mut self, mut sigma: S, mut effect: F)
203    where
204        S: FnMut() -> I,
205        I: IntoIterator<Item = B>,
206        B: Borrow<T::Input>,
207        F: FnMut(&M::T, &T::Output) -> M::T,
208    {
209        for (state, value) in self.dp.drain() {
210            for input in sigma() {
211                if let Some((nstate, output)) = self.fst.relation(&state, input.borrow()) {
212                    let nvalue = effect(&value, &output);
213                    self.ndp
214                        .entry(nstate)
215                        .and_modify(|acc| M::operate_assign(acc, &nvalue))
216                        .or_insert(nvalue);
217                }
218            }
219        }
220        swap(&mut self.dp, &mut self.ndp);
221        self.fst.stepout();
222    }
223    pub fn fold_accept(&self) -> M::T {
224        let mut acc = M::unit();
225        for (state, value) in self.dp.iter() {
226            if self.fst.accept(state) {
227                M::operate_assign(&mut acc, value);
228            }
229        }
230        acc
231    }
232    pub fn map_fold_accept<U, F, D>(&self, mut f: F, mut map: D) -> D
233    where
234        F: FnMut(&T::State) -> U,
235        D: Container<Key = U, Value = M::T>,
236    {
237        for (state, value) in self.dp.iter() {
238            if self.fst.accept(state) {
239                map.entry(f(state))
240                    .and_modify(|acc| M::operate_assign(acc, value))
241                    .or_insert_with(|| value.clone());
242            }
243        }
244        map
245    }
crates/competitive/src/algorithm/sqrt_decomposition.rs (line 95)
84    pub fn fold<R>(&self, range: R) -> <S::M as Magma>::T
85    where
86        R: RangeBounds<usize>,
87    {
88        let range = range.to_range_bounded(0, self.n).expect("invalid range");
89        let mut res = S::M::unit();
90        for (i, Bucket { cells, bucket }) in self.buckets.iter().enumerate() {
91            let s = i * self.bucket_size;
92            let t = s + cells.len();
93            if t <= range.start || range.end <= s {
94            } else if range.start <= s && t <= range.end {
95                <S::M as Magma>::operate_assign(&mut res, &S::fold_bucket(bucket));
96            } else {
97                for cell in &cells[range.start.max(s) - s..range.end.min(t) - s] {
98                    <S::M as Magma>::operate_assign(&mut res, &S::fold_cell(bucket, cell));
99                }
100            }
101        }
102        res
103    }
104}
105
106pub struct RangeUpdateRangeFoldSqrtDecomposition<M>
107where
108    M: Monoid,
109{
110    _marker: PhantomData<fn() -> M>,
111}
112
113impl<M> SqrtDecomposition for RangeUpdateRangeFoldSqrtDecomposition<M>
114where
115    M: Monoid,
116{
117    type M = M;
118    // fold, lazy, size
119    type B = (M::T, M::T, usize);
120    fn bucket(bsize: usize) -> Self::B {
121        (M::unit(), M::unit(), bsize)
122    }
123    fn update_bucket(bucket: &mut Self::B, x: &<Self::M as Magma>::T) {
124        M::operate_assign(&mut bucket.1, x);
125    }
126    fn update_cell(
127        bucket: &mut Self::B,
128        cell: &mut <Self::M as Magma>::T,
129        x: &<Self::M as Magma>::T,
130    ) {
131        M::operate_assign(&mut bucket.0, x);
132        M::operate_assign(cell, x);
133    }

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl Magma for ()

Source§

type T = ()

Source§

fn operate(_x: &Self::T, _y: &Self::T) -> Self::T

Source§

impl<A: Magma> Magma for (A,)

Source§

type T = (<A as Magma>::T,)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma> Magma for (A, B)

Source§

type T = (<A as Magma>::T, <B as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma> Magma for (A, B, C)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma> Magma for (A, B, C, D)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma> Magma for (A, B, C, D, E)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma, F: Magma> Magma for (A, B, C, D, E, F)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T, <F as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma, F: Magma, G: Magma> Magma for (A, B, C, D, E, F, G)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T, <F as Magma>::T, <G as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma, F: Magma, G: Magma, H: Magma> Magma for (A, B, C, D, E, F, G, H)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T, <F as Magma>::T, <G as Magma>::T, <H as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma, F: Magma, G: Magma, H: Magma, I: Magma> Magma for (A, B, C, D, E, F, G, H, I)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T, <F as Magma>::T, <G as Magma>::T, <H as Magma>::T, <I as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Source§

impl<A: Magma, B: Magma, C: Magma, D: Magma, E: Magma, F: Magma, G: Magma, H: Magma, I: Magma, J: Magma> Magma for (A, B, C, D, E, F, G, H, I, J)

Source§

type T = (<A as Magma>::T, <B as Magma>::T, <C as Magma>::T, <D as Magma>::T, <E as Magma>::T, <F as Magma>::T, <G as Magma>::T, <H as Magma>::T, <I as Magma>::T, <J as Magma>::T)

Source§

fn operate(x: &Self::T, y: &Self::T) -> Self::T

Implementors§

Source§

impl Magma for Gf2_63

Source§

type T = u64

Source§

impl Magma for Mersenne61

Source§

type T = u64

Source§

impl Magma for PermutationOperation

Source§

impl Magma for Mersenne61Add

Source§

type T = u64

Source§

impl Magma for SumMinimum

Source§

impl<M> Magma for CountingOperation<M>
where M: Magma<T: PartialEq> + Idempotent,

Source§

type T = (<M as Magma>::T, usize)

Source§

impl<M> Magma for ReverseOperation<M>
where M: Magma,

Source§

type T = <M as Magma>::T

Source§

impl<M, const N: usize> Magma for ArrayOperation<M, N>
where M: Magma,

Source§

type T = [<M as Magma>::T; N]

Source§

impl<R> Magma for FloorPowerSum<R>
where R: SemiRing,

Source§

impl<R, const X: usize, const Y: usize> Magma for FloorSum<R, X, Y>
where R: SemiRing,

Source§

type T = FloorSumData<R, X, Y>

Source§

impl<T> Magma for AdditiveOperation<T>
where T: Clone + Zero + Add<Output = T>,

Source§

type T = T

Source§

impl<T> Magma for BitAndOperation<T>
where T: Clone + BitAndIdentity,

Source§

type T = T

Source§

impl<T> Magma for BitOrOperation<T>
where T: Clone + BitOrIdentity,

Source§

type T = T

Source§

impl<T> Magma for BitXorOperation<T>
where T: Clone + BitXorIdentity,

Source§

type T = T

Source§

impl<T> Magma for ConcatenateOperation<T>
where T: Clone,

Source§

type T = Vec<T>

Source§

impl<T> Magma for FindMajorityOperation<T>
where T: Clone + Eq,

Source§

type T = (Option<T>, usize)

Source§

impl<T> Magma for FirstOperation<T>
where T: Clone,

Source§

type T = Option<T>

Source§

impl<T> Magma for LastOperation<T>
where T: Clone,

Source§

type T = Option<T>

Source§

impl<T> Magma for LinearOperation<T>
where T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,

Source§

impl<T> Magma for LogicalLinearOperation<T>
where T: Clone + BitXorIdentity + BitAndIdentity + BitXor<Output = T> + BitAnd<Output = T>,

Source§

impl<T> Magma for MaxOperation<T>
where T: Clone + Ord + Bounded,

Source§

type T = T

Source§

impl<T> Magma for MinOperation<T>
where T: Clone + Ord + Bounded,

Source§

type T = T

Source§

impl<T> Magma for MinimumIntervalMovementOperation<T>
where T: Clone + Ord + Add<Output = T> + Sub<Output = T> + Zero,

Source§

impl<T> Magma for MultiplicativeOperation<T>
where T: Clone + One + Mul<Output = T>,

Source§

type T = T

Source§

impl<T> Magma for RangeChminChmaxAdd<T>
where T: Copy + Zero + One + Ord + Bounded + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + PartialEq,

Source§

impl<T> Magma for RangeSumRangeChminChmaxAdd<T>
where T: Copy + Zero + One + Ord + Bounded + Add<Output = T> + Sub<Output = T> + Mul<Output = T> + PartialEq,

Source§

impl<T> Magma for SortedConcatenateOperation<T>
where T: Clone + Ord,

Source§

type T = Vec<T>

Source§

impl<const K: usize, T> Magma for BottomkOperation<K, T>
where T: Clone + Ord + Bounded,

Source§

impl<const K: usize, T> Magma for TopkOperation<K, T>
where T: Clone + Ord + Bounded,

Source§

impl<const K: usize, T, U> Magma for DedupedBottomkOperation<K, T, U>
where T: Clone + Ord + Bounded, U: Clone + Eq,

Source§

type T = [(T, Option<U>); K]

Source§

impl<const K: usize, T, U> Magma for DedupedTopkOperation<K, T, U>
where T: Clone + Ord + Bounded, U: Clone + Eq,

Source§

type T = [(T, Option<U>); K]