use std::marker::PhantomData;
use crate::{
algebraic_structure::{
monoid::Monoid,
operation::{Max, Min},
},
data_structure::segment_tree::SegmentTree,
utils::num_traits::Bounded,
};
pub struct Indexed<M: Monoid>(PhantomData<M>);
impl<T: Ord + Bounded + Clone> Monoid for Indexed<Min<T>> {
type Val = (T, usize);
fn id() -> Self::Val {
(Min::id(), usize::MAX)
}
fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
if left <= right {
left.clone()
} else {
right.clone()
}
}
}
impl<T: Ord + Bounded + Clone> SegmentTree<Indexed<Min<T>>> {
pub fn new_with_index(N: usize) -> Self {
let arr = (0..N).map(|i| (Min::id(), i));
Self::from_iter(arr)
}
}
impl<T: Ord + Bounded + Clone> Monoid for Indexed<Max<T>> {
type Val = (T, usize);
fn id() -> Self::Val {
(Max::id(), usize::MAX)
}
fn op(left: &Self::Val, right: &Self::Val) -> Self::Val {
if left >= right {
left.clone()
} else {
right.clone()
}
}
}
impl<T: Ord + Bounded + Clone> SegmentTree<Indexed<Max<T>>> {
pub fn new_with_index(N: usize) -> Self {
let arr = (0..N).map(|i| (Max::id(), i));
Self::from_iter(arr)
}
}