pub mod data_structure {
use num::Integer;
pub trait Monoid {
fn e() -> Self;
fn op(&self, rhs: Self) -> Self;
}
pub struct SegmentTree<T> {
n: usize, // m <= n となる最大の 2 の冪乗
m: usize, // 元の配列の長さ
val: Vec<T>,
}
impl<T: Monoid + Copy> SegmentTree<T> {
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 mut n = 1;
while n < m {
n <<= 1;
}
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]);
}
Self { n, m, val }
}
pub fn get(&self, pos: usize) -> T {
self.val[pos + self.n]
}
pub fn set(&mut self, pos: usize, x: T) {
let mut i = pos + self.n;
self.val[i] = x;
while i > 1 {
i >>= 1;
let l = i << 1;
let r = (i << 1) + 1;
self.val[i] = self.val[l].op(self.val[r]);
}
}
pub fn prod<R>(&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;
let mut v = T::e();
while l < r {
if (l & 1) == 1 {
v = v.op(self.val[l]);
l += 1;
}
if (r & 1) == 1 {
r -= 1;
v = v.op(self.val[r]);
}
l >>= 1;
r >>= 1;
}
v
}
/// find max r such that f(prod(l, r)) is true
pub fn max_right<F>(&self, l: usize, f: F) -> usize
where
F: Fn(T) -> bool,
{
let mut l = l + self.n;
let mut current_prod = T::e();
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 {
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>(&self, r: usize, f: F) -> usize
where
F: Fn(T) -> bool,
{
let mut r = r + self.n;
let mut current_prod = T::e();
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 {
r = (r << 1) | 1;
let next = self.val[r].op(current_prod);
if f(next) {
current_prod = next;
r -= 1;
}
}
r + 1 - self.n
}
/// 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)
}
}
}