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/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    }
crates/competitive/src/data_structure/submask_range_query.rs (line 171)
152    pub fn solve(self) -> Vec<G::T> {
153        let s = SubmaskRangeQuery::new_with_queries(self.query.iter().map(|q| match q {
154            Query::Get { m } => (QueryKind::Get, *m),
155            Query::Update { m, .. } => (QueryKind::Update, *m),
156        }));
157        let out_size = self
158            .query
159            .iter()
160            .filter(|q| matches!(q, Query::Get { .. }))
161            .count();
162        let mut out = Vec::with_capacity(out_size);
163        let mut data = vec![G::unit(); 1 << s.bit_width];
164        for q in self.query {
165            match q {
166                Query::Get { m } => {
167                    let mut f = G::unit();
168                    let mut g = G::unit();
169                    for (k, inv) in s.get_query(m) {
170                        if inv {
171                            G::operate_assign(&mut g, &data[k as usize]);
172                        } else {
173                            G::operate_assign(&mut f, &data[k as usize]);
174                        }
175                    }
176                    out.push(G::rinv_operate(&f, &g));
177                }
178                Query::Update { m, x } => {
179                    for k in s.update_query(m) {
180                        G::operate_assign(&mut data[k as usize], &x);
181                    }
182                }
183            }
184        }
185        out
186    }

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.

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<D: LcaMonoidDispatch> Magma for LcaMonoid<D>

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,