ac-library-hs-1.1.0.0: src/AtCoder/Extra/Monoid/RangeSet.hs
{-# LANGUAGE TypeFamilies #-}
-- | Monoid action \(f: x \rightarrow a\).
--
-- @since 1.0.0.0
module AtCoder.Extra.Monoid.RangeSet
( -- * RangeSet
RangeSet (..),
RangeSetRepr,
-- * Constructors
new,
unRangeSet,
-- * Actions
act,
)
where
import AtCoder.LazySegTree (SegAct (..))
import Data.Bit (Bit (..))
import Data.Semigroup (stimes)
import Data.Vector.Generic qualified as VG
import Data.Vector.Generic.Mutable qualified as VGM
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
-- | Monoid action \(f: x \rightarrow a\).
--
-- ==== __Example__
-- >>> import AtCoder.Extra.Monoid (SegAct(..), RangeSet(..))
-- >>> import AtCoder.LazySegTree qualified as LST
-- >>> import Data.Bit (Bit (..))
-- >>> import Data.Semigroup (Product(..))
-- >>> seg <- LST.build @_ @(RangeSet (Product Int)) @(Product Int) $ VU.generate 4 Product -- [0, 1, 2, 3]
-- >>> LST.applyIn seg 0 3 $ RangeSet (Bit True, Product 5) -- [5, 5, 5, 3]
-- >>> getProduct <$> LST.prod seg 0 4
-- 375
--
-- @since 1.0.0.0
newtype RangeSet a = RangeSet (RangeSetRepr a)
deriving newtype
( -- | @since 1.0.0.0
Eq,
-- | @since 1.0.0.0
Ord,
-- | @since 1.0.0.0
Show
)
-- | `RangeSet` internal representation. The first value represents if it is an identity action.
-- Tuples are not the fastest representation, but it's easier to implement
-- `Data.Vector.Unboxed.Unbox`.
--
-- @since 1.1.0.0
type RangeSetRepr a = (Bit, a)
-- | \(O(1)\) Creates a new `RangeSet` action.
--
-- @since 1.0.0.0
{-# INLINE new #-}
new :: a -> RangeSet a
new = RangeSet . (Bit True,)
-- | \(O(1)\) Retrieves the internal representation of `RangeSet`.
--
-- @since 1.1.0.0
{-# INLINE unRangeSet #-}
unRangeSet :: RangeSet a -> RangeSetRepr a
unRangeSet (RangeSet a) = a
-- | \(O(1)\) Applies one-length range set: \(f: x \rightarrow y\).
--
-- @since 1.0.0.0
{-# INLINE act #-}
act :: RangeSet a -> a -> a
act (RangeSet (Bit True, !f)) _ = f
act (RangeSet (Bit False, !_)) x = x
-- | Acts on @a@ with length in terms of `SegAct`.
--
-- @since 1.0.0.0
{-# INLINE actWithLength #-}
actWithLength :: (Semigroup a) => Int -> RangeSet a -> a -> a
actWithLength len (RangeSet (Bit True, !f)) _ = stimes len f
actWithLength _ (RangeSet (Bit False, !_)) x = x
-- | @since 1.0.0.0
instance Semigroup (RangeSet a) where
{-# INLINE (<>) #-}
RangeSet (Bit False, !_) <> old = old
new_ <> _ = new_
{-# INLINE stimes #-}
stimes _ x = x
-- | @since 1.0.0.0
instance (Monoid a) => Monoid (RangeSet a) where
{-# INLINE mempty #-}
mempty = RangeSet (Bit False, mempty)
{-# INLINE mconcat #-}
-- find the first non-mempty
mconcat [] = mempty
mconcat (RangeSet (Bit False, !_) : as) = mconcat as
mconcat (a : _) = a
-- | @since 1.0.0.0
instance (Monoid a) => SegAct (RangeSet a) a where
{-# INLINE segActWithLength #-}
segActWithLength = actWithLength
-- | @since 1.0.0.0
newtype instance VU.MVector s (RangeSet a) = MV_RangeSet (VU.MVector s (RangeSetRepr a))
-- | @since 1.0.0.0
newtype instance VU.Vector (RangeSet a) = V_RangeSet (VU.Vector (RangeSetRepr a))
-- | @since 1.0.0.0
deriving instance (VU.Unbox a) => VGM.MVector VUM.MVector (RangeSet a)
-- | @since 1.0.0.0
deriving instance (VU.Unbox a) => VG.Vector VU.Vector (RangeSet a)
-- | @since 1.0.0.0
instance (VU.Unbox a) => VU.Unbox (RangeSet a)