mod data_structure {
pub trait Monoid {
fn e() -> Self;
fn op(&self, rhs: &Self) -> Self;
}
pub trait Operator<T: Monoid> {
fn mapping(&self, x: &T) -> T;
fn composition(&self, rhs: &Self) -> Self;
fn id() -> Self;
}
pub struct LazySegmentTree<T, U> {
n: usize, // length of leaf node
m: usize, // length of original array
depth: usize, // depth of tree, root's depth is 1
val: Vec<T>,
lazy: Vec<U>,
}
impl<T: Monoid, U: Operator<T>, I> From<I> for LazySegmentTree<T, U>
where
I: IntoIterator<Item = T>,
{
fn from(iter: I) -> Self {
Self::build(iter.into_iter().collect())
}
}
impl<T: Monoid, U: Operator<T>> LazySegmentTree<T, U> {
pub fn new(n: usize) -> Self {
Self::build(Self::build_identity_array(n))
}
fn build_identity_array(n: usize) -> Vec<T> {
(0..n).map(|_| T::e()).collect()
}
fn build(v: Vec<T>) -> Self {
let m = v.len();
let n = bit_ceil(m);
let depth = bit_width(n);
let mut val = Self::build_identity_array(n); // n
val.extend(v); // n + m
val.extend(Self::build_identity_array(n - m)); // 2n
for i in (1..n).rev() {
let l = i << 1;
let r = (i << 1) + 1;
val[i] = val[l].op(&val[r]);
}
let lazy = (0..n).map(|_| U::id()).collect();
Self {
n,
m,
depth,
val,
lazy,
}
}
pub fn get(&mut self, pos: usize) -> &T {
let i = pos + self.n;
for d in (1..self.depth).rev() {
self.propagate(i >> d);
}
&self.val[i]
}
pub fn set(&mut self, pos: usize, x: T) {
let i = pos + self.n;
for d in (1..self.depth).rev() {
self.propagate(i >> d);
}
self.val[i] = x;
for d in 1..self.depth {
self.update(i >> d);
}
}
pub fn apply<R>(&mut self, range: R, f: U)
where
R: std::ops::RangeBounds<usize>,
{
let (mut l, mut r) = self.to_half_open_pair(range);
l += self.n;
r += self.n;
for d in (1..self.depth).rev() {
if ((l >> d) << d) != l {
self.propagate(l >> d);
}
if ((r >> d) << d) != r {
self.propagate((r - 1) >> d);
}
}
{
let (l2, r2) = (l, r);
while l < r {
if (l & 1) == 1 {
self.apply_to_node(l, &f);
l += 1;
}
if (r & 1) == 1 {
r -= 1;
self.apply_to_node(r, &f);
}
l >>= 1;
r >>= 1;
}
(l, r) = (l2, r2);
}
for d in 1..self.depth {
if ((l >> d) << d) != l {
self.update(l >> d);
}
if ((r >> d) << d) != r {
self.update((r - 1) >> d);
}
}
}
pub fn prod<R>(&mut self, range: R) -> T
where
R: std::ops::RangeBounds<usize>,
{
let (mut l, mut r) = self.to_half_open_pair(range);
l += self.n;
r += self.n;
for d in (1..self.depth).rev() {
if ((l >> d) << d) != l {
self.propagate(l >> d);
}
if ((r >> d) << d) != r {
self.propagate((r - 1) >> d);
}
}
let (mut vl, mut vr) = (T::e(), T::e());
while l < r {
if (l & 1) == 1 {
vl = vl.op(&self.val[l]);
l += 1;
}
if (r & 1) == 1 {
r -= 1;
vr = self.val[r].op(&vr);
}
l >>= 1;
r >>= 1;
}
vl.op(&vr)
}
/// find max r such that f(prod(l, r)) is true
pub fn max_right<F>(&mut self, l: usize, f: F) -> usize
where
F: Fn(&T) -> bool,
{
let mut l = l + self.n;
let mut current_prod = T::e();
for d in (1..self.depth).rev() {
self.propagate(l >> d);
}
loop {
while (l & 1) == 0 {
l >>= 1;
}
let next = current_prod.op(&self.val[l]);
if !f(&next) {
break;
}
current_prod = next;
l += 1;
if l.is_power_of_two() {
return self.m;
}
}
while l < self.n {
self.propagate(l);
l <<= 1;
let next = current_prod.op(&self.val[l]);
if f(&next) {
current_prod = next;
l += 1;
}
}
l - self.n
}
/// find min l such that f(prod(l, r)) is true
pub fn min_left<F>(&mut self, r: usize, f: F) -> usize
where
F: Fn(&T) -> bool,
{
let mut r = r + self.n;
let mut current_prod = T::e();
for d in (1..self.depth).rev() {
self.propagate((r - 1) >> d);
}
loop {
r -= 1;
while r > 1 && (r & 1) == 1 {
r >>= 1;
}
let next = self.val[r].op(¤t_prod);
if !f(&next) {
break;
}
current_prod = next;
if r.is_power_of_two() {
return 0;
}
}
while r < self.n {
self.propagate(r);
r = (r << 1) | 1;
let next = self.val[r].op(¤t_prod);
if f(&next) {
current_prod = next;
r -= 1;
}
}
r + 1 - self.n
}
fn update(&mut self, k: usize) {
if k >= self.n {
return;
}
self.val[k] = self.val[k << 1].op(&self.val[(k << 1) + 1]);
}
fn apply_to_node(&mut self, k: usize, f: &U) {
self.val[k] = f.mapping(&self.val[k]);
if k < self.n {
self.lazy[k] = f.composition(&self.lazy[k]);
}
}
fn propagate(&mut self, k: usize) {
let f = std::mem::replace(&mut self.lazy[k], U::id());
for i in 0..2 {
let ch = (k << 1) + i;
self.apply_to_node(ch, &f);
}
}
/// range = [l, r) と表せる (l, r) を返す
fn to_half_open_pair<R>(&self, range: R) -> (usize, usize)
where
R: std::ops::RangeBounds<usize>,
{
let l = match range.start_bound() {
std::ops::Bound::Included(&l) => l,
std::ops::Bound::Excluded(&l) => l + 1,
std::ops::Bound::Unbounded => 0,
};
let r = match range.end_bound() {
std::ops::Bound::Included(&r) => r + 1,
std::ops::Bound::Excluded(&r) => r,
std::ops::Bound::Unbounded => self.m,
};
(l, r)
}
}
fn bit_ceil(x: usize) -> usize {
if x.is_power_of_two() {
x
} else {
fill_one(x) + 1
}
}
fn bit_width(x: usize) -> usize {
x.ilog2() as usize + 1
}
fn fill_one(mut x: usize) -> usize {
for i in 0..=5 {
x |= x >> (1 << i);
}
x
}
}