{-# 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
      RangeSet a -> RangeSet a -> Bool
(RangeSet a -> RangeSet a -> Bool)
-> (RangeSet a -> RangeSet a -> Bool) -> Eq (RangeSet a)
forall a. Eq a => RangeSet a -> RangeSet a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => RangeSet a -> RangeSet a -> Bool
== :: RangeSet a -> RangeSet a -> Bool
$c/= :: forall a. Eq a => RangeSet a -> RangeSet a -> Bool
/= :: RangeSet a -> RangeSet a -> Bool
Eq,
      -- | @since 1.0.0.0
      Eq (RangeSet a)
Eq (RangeSet a) =>
(RangeSet a -> RangeSet a -> Ordering)
-> (RangeSet a -> RangeSet a -> Bool)
-> (RangeSet a -> RangeSet a -> Bool)
-> (RangeSet a -> RangeSet a -> Bool)
-> (RangeSet a -> RangeSet a -> Bool)
-> (RangeSet a -> RangeSet a -> RangeSet a)
-> (RangeSet a -> RangeSet a -> RangeSet a)
-> Ord (RangeSet a)
RangeSet a -> RangeSet a -> Bool
RangeSet a -> RangeSet a -> Ordering
RangeSet a -> RangeSet a -> RangeSet a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (RangeSet a)
forall a. Ord a => RangeSet a -> RangeSet a -> Bool
forall a. Ord a => RangeSet a -> RangeSet a -> Ordering
forall a. Ord a => RangeSet a -> RangeSet a -> RangeSet a
$ccompare :: forall a. Ord a => RangeSet a -> RangeSet a -> Ordering
compare :: RangeSet a -> RangeSet a -> Ordering
$c< :: forall a. Ord a => RangeSet a -> RangeSet a -> Bool
< :: RangeSet a -> RangeSet a -> Bool
$c<= :: forall a. Ord a => RangeSet a -> RangeSet a -> Bool
<= :: RangeSet a -> RangeSet a -> Bool
$c> :: forall a. Ord a => RangeSet a -> RangeSet a -> Bool
> :: RangeSet a -> RangeSet a -> Bool
$c>= :: forall a. Ord a => RangeSet a -> RangeSet a -> Bool
>= :: RangeSet a -> RangeSet a -> Bool
$cmax :: forall a. Ord a => RangeSet a -> RangeSet a -> RangeSet a
max :: RangeSet a -> RangeSet a -> RangeSet a
$cmin :: forall a. Ord a => RangeSet a -> RangeSet a -> RangeSet a
min :: RangeSet a -> RangeSet a -> RangeSet a
Ord,
      -- | @since 1.0.0.0
      Int -> RangeSet a -> ShowS
[RangeSet a] -> ShowS
RangeSet a -> String
(Int -> RangeSet a -> ShowS)
-> (RangeSet a -> String)
-> ([RangeSet a] -> ShowS)
-> Show (RangeSet a)
forall a. Show a => Int -> RangeSet a -> ShowS
forall a. Show a => [RangeSet a] -> ShowS
forall a. Show a => RangeSet a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> RangeSet a -> ShowS
showsPrec :: Int -> RangeSet a -> ShowS
$cshow :: forall a. Show a => RangeSet a -> String
show :: RangeSet a -> String
$cshowList :: forall a. Show a => [RangeSet a] -> ShowS
showList :: [RangeSet a] -> ShowS
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 :: forall a. a -> RangeSet a
new = RangeSetRepr a -> RangeSet a
forall a. RangeSetRepr a -> RangeSet a
RangeSet (RangeSetRepr a -> RangeSet a)
-> (a -> RangeSetRepr a) -> a -> RangeSet a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Bool -> Bit
Bit Bool
True,)

-- | \(O(1)\) Retrieves the internal representation of `RangeSet`.
--
-- @since 1.1.0.0
{-# INLINE unRangeSet #-}
unRangeSet :: RangeSet a -> RangeSetRepr a
unRangeSet :: forall a. RangeSet a -> RangeSetRepr a
unRangeSet (RangeSet RangeSetRepr a
a) = RangeSetRepr 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 :: forall a. RangeSet a -> a -> a
act (RangeSet (Bit Bool
True, !a
f)) a
_ = a
f
act (RangeSet (Bit Bool
False, !a
_)) a
x = a
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 :: forall a. Semigroup a => Int -> RangeSet a -> a -> a
actWithLength Int
len (RangeSet (Bit Bool
True, !a
f)) a
_ = Int -> a -> a
forall b. Integral b => b -> a -> a
forall a b. (Semigroup a, Integral b) => b -> a -> a
stimes Int
len a
f
actWithLength Int
_ (RangeSet (Bit Bool
False, !a
_)) a
x = a
x

-- | @since 1.0.0.0
instance Semigroup (RangeSet a) where
  {-# INLINE (<>) #-}
  RangeSet (Bit Bool
False, !a
_) <> :: RangeSet a -> RangeSet a -> RangeSet a
<> RangeSet a
old = RangeSet a
old
  RangeSet a
new_ <> RangeSet a
_ = RangeSet a
new_
  {-# INLINE stimes #-}
  stimes :: forall b. Integral b => b -> RangeSet a -> RangeSet a
stimes b
_ RangeSet a
x = RangeSet a
x

-- | @since 1.0.0.0
instance (Monoid a) => Monoid (RangeSet a) where
  {-# INLINE mempty #-}
  mempty :: RangeSet a
mempty = RangeSetRepr a -> RangeSet a
forall a. RangeSetRepr a -> RangeSet a
RangeSet (Bool -> Bit
Bit Bool
False, a
forall a. Monoid a => a
mempty)
  {-# INLINE mconcat #-}
  -- find the first non-mempty
  mconcat :: [RangeSet a] -> RangeSet a
mconcat [] = RangeSet a
forall a. Monoid a => a
mempty
  mconcat (RangeSet (Bit Bool
False, !a
_) : [RangeSet a]
as) = [RangeSet a] -> RangeSet a
forall a. Monoid a => [a] -> a
mconcat [RangeSet a]
as
  mconcat (RangeSet a
a : [RangeSet a]
_) = RangeSet a
a

-- | @since 1.0.0.0
instance (Monoid a) => SegAct (RangeSet a) a where
  {-# INLINE segActWithLength #-}
  segActWithLength :: Int -> RangeSet a -> a -> a
segActWithLength = Int -> RangeSet a -> a -> a
forall a. Semigroup a => Int -> RangeSet a -> a -> a
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)