pub mod data_structure {
use num::Integer;
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;
}
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<Option<U>>,
}
impl<T: Monoid + Copy, U: Operator<T> + Copy> LazySegmentTree<T, U> {
pub fn from_length(n: usize) -> Self {
let val = vec![T::e(); n];
Self::build(val)
}
pub fn from_array(v: &[T]) -> Self {
let val = v.to_vec();
Self::build(val)
}
fn build(v: Vec<T>) -> Self {
let m = v.len();
let n = bit_ceil(m);
let depth = bit_width(n);
let mut val = vec![T::e(); n]; // n
val.extend(v); // n + m
val.extend(vec![T::e(); 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 = vec![None; n];
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[pos + self.n]
}
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.is_even() {
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.is_odd() {
r >>= 1;
}
let next = self.val[r].op(current_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(current_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] = if let Some(lz) = self.lazy[k] {
Some(f.composition(lz))
} else {
Some(f)
}
}
}
fn propagate(&mut self, k: usize) {
if let Some(lz) = self.lazy[k].take() {
for i in 0..2 {
let j = (k << 1) + i;
self.apply_to_node(j, lz);
}
}
}
/// 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
}
}