Skip to content

Commit 33dc514

Browse files
Merge pull request #115 from mizar/segtree
Segtree: Monoid BitOrOper/BitAndOper/BitXorOper, FromIterator, get_slice
2 parents 71c3474 + 4d0dc0b commit 33dc514

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ pub use modint::{
2929
ModInt1000000007, ModInt998244353, Modulus, RemEuclidU32, StaticModInt,
3030
};
3131
pub use scc::SccGraph;
32-
pub use segtree::{Additive, Max, Min, Monoid, Multiplicative, Segtree};
32+
pub use segtree::{
33+
Additive, BitwiseAnd, BitwiseOr, BitwiseXor, Max, Min, Monoid, Multiplicative, Segtree,
34+
};
3335
pub use string::{
3436
lcp_array, lcp_array_arbitrary, suffix_array, suffix_array_arbitrary, suffix_array_manual,
3537
z_algorithm, z_algorithm_arbitrary,

src/segtree.rs

+69-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use crate::internal_bit::ceil_pow2;
22
use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
33
use std::cmp::{max, min};
44
use std::convert::Infallible;
5+
use std::iter::FromIterator;
56
use std::marker::PhantomData;
6-
use std::ops::{Add, Bound, Mul, RangeBounds};
7+
use std::ops::{Add, BitAnd, BitOr, BitXor, Bound, Mul, Not, RangeBounds};
78

89
// TODO Should I split monoid-related traits to another module?
910
pub trait Monoid {
@@ -68,6 +69,48 @@ where
6869
}
6970
}
7071

72+
pub struct BitwiseOr<S>(Infallible, PhantomData<fn() -> S>);
73+
impl<S> Monoid for BitwiseOr<S>
74+
where
75+
S: Copy + BitOr<Output = S> + Zero,
76+
{
77+
type S = S;
78+
fn identity() -> Self::S {
79+
S::zero()
80+
}
81+
fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
82+
*a | *b
83+
}
84+
}
85+
86+
pub struct BitwiseAnd<S>(Infallible, PhantomData<fn() -> S>);
87+
impl<S> Monoid for BitwiseAnd<S>
88+
where
89+
S: Copy + BitAnd<Output = S> + Not<Output = S> + Zero,
90+
{
91+
type S = S;
92+
fn identity() -> Self::S {
93+
!S::zero()
94+
}
95+
fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
96+
*a & *b
97+
}
98+
}
99+
100+
pub struct BitwiseXor<S>(Infallible, PhantomData<fn() -> S>);
101+
impl<S> Monoid for BitwiseXor<S>
102+
where
103+
S: Copy + BitXor<Output = S> + Zero,
104+
{
105+
type S = S;
106+
fn identity() -> Self::S {
107+
S::zero()
108+
}
109+
fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
110+
*a ^ *b
111+
}
112+
}
113+
71114
impl<M: Monoid> Default for Segtree<M> {
72115
fn default() -> Self {
73116
Segtree::new(0)
@@ -84,7 +127,27 @@ impl<M: Monoid> From<Vec<M::S>> for Segtree<M> {
84127
let log = ceil_pow2(n as u32) as usize;
85128
let size = 1 << log;
86129
let mut d = vec![M::identity(); 2 * size];
87-
d[size..(size + n)].clone_from_slice(&v);
130+
d[size..][..n].clone_from_slice(&v);
131+
let mut ret = Segtree { n, size, log, d };
132+
for i in (1..size).rev() {
133+
ret.update(i);
134+
}
135+
ret
136+
}
137+
}
138+
impl<M: Monoid> FromIterator<M::S> for Segtree<M> {
139+
fn from_iter<T: IntoIterator<Item = M::S>>(iter: T) -> Self {
140+
let iter = iter.into_iter();
141+
let n = iter.size_hint().0;
142+
let log = ceil_pow2(n as u32) as usize;
143+
let size = 1 << log;
144+
let mut d = Vec::with_capacity(size * 2);
145+
d.extend(
146+
std::iter::repeat_with(M::identity)
147+
.take(size)
148+
.chain(iter)
149+
.chain(std::iter::repeat_with(M::identity).take(size - n)),
150+
);
88151
let mut ret = Segtree { n, size, log, d };
89152
for i in (1..size).rev() {
90153
ret.update(i);
@@ -107,6 +170,10 @@ impl<M: Monoid> Segtree<M> {
107170
self.d[p + self.size].clone()
108171
}
109172

173+
pub fn get_slice(&self) -> &[M::S] {
174+
&self.d[self.size..][..self.n]
175+
}
176+
110177
pub fn prod<R>(&self, range: R) -> M::S
111178
where
112179
R: RangeBounds<usize>,

0 commit comments

Comments
 (0)