{-# LANGUAGE RecordWildCards #-}
module AtCoder.Extra.WaveletMatrix
(
WaveletMatrix (..),
build,
access,
rank,
rankBetween,
select,
selectKth,
selectIn,
selectKthIn,
kthLargestIn,
ikthLargestIn,
kthSmallestIn,
ikthSmallestIn,
lookupLE,
lookupLT,
lookupGE,
lookupGT,
assocsIn,
descAssocsIn,
)
where
import AtCoder.Extra.Bisect
import AtCoder.Extra.WaveletMatrix.Raw qualified as Rwm
import Control.Monad
import Data.Maybe (fromJust, fromMaybe)
import Data.Vector.Algorithms.Intro qualified as VAI
import Data.Vector.Generic qualified as VG
import Data.Vector.Unboxed qualified as VU
data WaveletMatrix = WaveletMatrix
{
WaveletMatrix -> RawWaveletMatrix
rawWM :: !Rwm.RawWaveletMatrix,
WaveletMatrix -> Vector Int
xDictWM :: !(VU.Vector Int)
}
{-# INLINE build #-}
build :: VU.Vector Int -> WaveletMatrix
build :: Vector Int -> WaveletMatrix
build Vector Int
ys =
let !xDictWM :: Vector Int
xDictWM = Vector Int -> Vector Int
forall a. (Unbox a, Eq a) => Vector a -> Vector a
VU.uniq (Vector Int -> Vector Int) -> Vector Int -> Vector Int
forall a b. (a -> b) -> a -> b
$ (forall s. MVector s Int -> ST s ()) -> Vector Int -> Vector Int
forall a.
Unbox a =>
(forall s. MVector s a -> ST s ()) -> Vector a -> Vector a
VU.modify (Comparison Int -> MVector (PrimState (ST s)) Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) e.
(PrimMonad m, MVector v e) =>
Comparison e -> v (PrimState m) e -> m ()
VAI.sortBy Comparison Int
forall a. Ord a => a -> a -> Ordering
compare) Vector Int
ys
!ys' :: Vector Int
ys' = (Int -> Int) -> Vector Int -> Vector Int
forall a b. (Unbox a, Unbox b) => (a -> b) -> Vector a -> Vector b
VU.map (Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Int -> Int) -> (Int -> Maybe Int) -> Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Int -> Maybe Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Maybe Int
lowerBound Vector Int
xDictWM) Vector Int
ys
!rawWM :: RawWaveletMatrix
rawWM = HasCallStack => Int -> Vector Int -> RawWaveletMatrix
Int -> Vector Int -> RawWaveletMatrix
Rwm.build (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
ys) Vector Int
ys'
in WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
xDictWM :: Vector Int
rawWM :: RawWaveletMatrix
..}
{-# INLINE access #-}
access :: WaveletMatrix -> Int -> Maybe Int
access :: WaveletMatrix -> Int -> Maybe Int
access WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
i = (Vector Int
xDictWM VG.!) (Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RawWaveletMatrix -> Int -> Maybe Int
Rwm.access RawWaveletMatrix
rawWM Int
i
{-# INLINE rank #-}
rank ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Int
rank :: WaveletMatrix -> Int -> Int -> Int -> Int
rank WaveletMatrix
wm Int
l Int
r Int
y = WaveletMatrix -> Int -> Int -> Int -> Int -> Int
rankBetween WaveletMatrix
wm Int
l Int
r Int
y (Int
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE rankBetween #-}
rankBetween ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Int ->
Int
rankBetween :: WaveletMatrix -> Int -> Int -> Int -> Int -> Int
rankBetween WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
y1 Int
y2
| Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
l Bool -> Bool -> Bool
&& Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
r Bool -> Bool -> Bool
&& Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
n = Int
0
| Int
y1' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
y2' = Int
0
| Bool
otherwise = RawWaveletMatrix -> Int -> Int -> Int -> Int -> Int
Rwm.rankBetween RawWaveletMatrix
rawWM Int
l Int
r Int
y1' Int
y2'
where
n :: Int
n = RawWaveletMatrix -> Int
Rwm.lengthRwm RawWaveletMatrix
rawWM
y1' :: Int
y1' = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
n (HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
Int -> Int -> (Int -> Bool) -> Maybe Int
bisectR Int
0 (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
xDictWM) ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
y1) (Int -> Bool) -> (Int -> Int) -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
VG.unsafeIndex Vector Int
xDictWM))
y2' :: Int
y2' = Int -> (Int -> Int) -> Maybe Int -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (-Int
1) (Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (HasCallStack => Int -> Int -> (Int -> Bool) -> Maybe Int
Int -> Int -> (Int -> Bool) -> Maybe Int
bisectL Int
0 (Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
xDictWM) ((Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
y2) (Int -> Bool) -> (Int -> Int) -> Int -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector Int -> Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int -> a
VG.unsafeIndex Vector Int
xDictWM))
{-# INLINE select #-}
select :: WaveletMatrix -> Int -> Maybe Int
select :: WaveletMatrix -> Int -> Maybe Int
select WaveletMatrix
wm = WaveletMatrix -> Int -> Int -> Maybe Int
selectKth WaveletMatrix
wm Int
0
{-# INLINE selectKth #-}
selectKth ::
WaveletMatrix ->
Int ->
Int ->
Maybe Int
selectKth :: WaveletMatrix -> Int -> Int -> Maybe Int
selectKth WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
k Int
y = do
Int
i <- Vector Int -> Int -> Maybe Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Maybe Int
lowerBound Vector Int
xDictWM Int
y
let !y' :: Int
y' = Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
i
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
y' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y
RawWaveletMatrix -> Int -> Int -> Maybe Int
Rwm.selectKth RawWaveletMatrix
rawWM Int
k Int
i
{-# INLINE selectIn #-}
selectIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
selectIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
selectIn WaveletMatrix
wm Int
l Int
r = WaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
selectKthIn WaveletMatrix
wm Int
l Int
r Int
0
{-# INLINE selectKthIn #-}
selectKthIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Int ->
Maybe Int
selectKthIn :: WaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
selectKthIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k Int
y = do
Int
i <- Vector Int -> Int -> Maybe Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Maybe Int
lowerBound Vector Int
xDictWM Int
y
let !y' :: Int
y' = Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
i
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
y' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
y
RawWaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
Rwm.selectKthIn RawWaveletMatrix
rawWM Int
l Int
r Int
k Int
i
{-# INLINE kthLargestIn #-}
kthLargestIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
kthLargestIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
kthLargestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k
| Just !Int
y <- RawWaveletMatrix -> Int -> Int -> Int -> Maybe Int
Rwm.kthLargestIn RawWaveletMatrix
rawWM Int
l Int
r Int
k = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
y
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
{-# INLINE ikthLargestIn #-}
ikthLargestIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe (Int, Int)
ikthLargestIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe (Int, Int)
ikthLargestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k
| Just (!Int
i, !Int
y) <- RawWaveletMatrix -> Int -> Int -> Int -> Maybe (Int, Int)
Rwm.ikthLargestIn RawWaveletMatrix
rawWM Int
l Int
r Int
k = (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
i, Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
y)
| Bool
otherwise = Maybe (Int, Int)
forall a. Maybe a
Nothing
{-# INLINE kthSmallestIn #-}
kthSmallestIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
kthSmallestIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
kthSmallestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k
| Just !Int
y <- RawWaveletMatrix -> Int -> Int -> Int -> Maybe Int
Rwm.kthSmallestIn RawWaveletMatrix
rawWM Int
l Int
r Int
k = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
y
| Bool
otherwise = Maybe Int
forall a. Maybe a
Nothing
{-# INLINE ikthSmallestIn #-}
ikthSmallestIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe (Int, Int)
ikthSmallestIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe (Int, Int)
ikthSmallestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k
| Just (!Int
i, !Int
y) <- RawWaveletMatrix -> Int -> Int -> Int -> Maybe (Int, Int)
Rwm.ikthSmallestIn RawWaveletMatrix
rawWM Int
l Int
r Int
k = (Int, Int) -> Maybe (Int, Int)
forall a. a -> Maybe a
Just (Int
i, Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! Int
y)
| Bool
otherwise = Maybe (Int, Int)
forall a. Maybe a
Nothing
{-# INLINE unsafeKthSmallestIn #-}
unsafeKthSmallestIn :: WaveletMatrix -> Int -> Int -> Int -> Int
unsafeKthSmallestIn :: WaveletMatrix -> Int -> Int -> Int -> Int
unsafeKthSmallestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r Int
k =
Vector Int
xDictWM Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a) =>
v a -> Int -> a
VG.! RawWaveletMatrix -> Int -> Int -> Int -> Int
Rwm.unsafeKthSmallestIn RawWaveletMatrix
rawWM Int
l Int
r Int
k
{-# INLINE lookupLE #-}
lookupLE ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
lookupLE :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupLE WaveletMatrix
wm Int
l Int
r Int
y0
| Int
r' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
l' = Maybe Int
forall a. Maybe a
Nothing
| Int
rank_ Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ WaveletMatrix -> Int -> Int -> Int -> Int
unsafeKthSmallestIn WaveletMatrix
wm Int
l' Int
r' (Int
rank_ Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
where
l' :: Int
l' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
l
r' :: Int
r' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (RawWaveletMatrix -> Int
Rwm.lengthRwm (WaveletMatrix -> RawWaveletMatrix
rawWM WaveletMatrix
wm)) Int
r
rank_ :: Int
rank_ = WaveletMatrix -> Int -> Int -> Int -> Int -> Int
rankBetween WaveletMatrix
wm Int
l' Int
r' Int
forall a. Bounded a => a
minBound (Int
y0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE lookupLT #-}
lookupLT ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
lookupLT :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupLT WaveletMatrix
wm Int
l Int
r Int
y0 = WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupLE WaveletMatrix
wm Int
l Int
r (Int
y0 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
{-# INLINE lookupGE #-}
lookupGE ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
lookupGE :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupGE WaveletMatrix
wm Int
l Int
r Int
y0
| Int
r' Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
l' = Maybe Int
forall a. Maybe a
Nothing
| Int
rank_ Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l = Maybe Int
forall a. Maybe a
Nothing
| Bool
otherwise = Int -> Maybe Int
forall a. a -> Maybe a
Just (Int -> Maybe Int) -> Int -> Maybe Int
forall a b. (a -> b) -> a -> b
$ WaveletMatrix -> Int -> Int -> Int -> Int
unsafeKthSmallestIn WaveletMatrix
wm Int
l Int
r Int
rank_
where
l' :: Int
l' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 Int
l
r' :: Int
r' = Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (RawWaveletMatrix -> Int
Rwm.lengthRwm (WaveletMatrix -> RawWaveletMatrix
rawWM WaveletMatrix
wm)) Int
r
rank_ :: Int
rank_ = WaveletMatrix -> Int -> Int -> Int -> Int -> Int
rankBetween WaveletMatrix
wm Int
l' Int
r' Int
forall a. Bounded a => a
minBound Int
y0
{-# INLINE lookupGT #-}
lookupGT ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
lookupGT :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupGT WaveletMatrix
wm Int
l Int
r Int
y0 = WaveletMatrix -> Int -> Int -> Int -> Maybe Int
lookupGE WaveletMatrix
wm Int
l Int
r (Int
y0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
{-# INLINE assocsIn #-}
assocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
assocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
assocsIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r = RawWaveletMatrix -> Int -> Int -> (Int -> Int) -> [(Int, Int)]
Rwm.assocsWith RawWaveletMatrix
rawWM Int
l Int
r (Vector Int
xDictWM VG.!)
{-# INLINE descAssocsIn #-}
descAssocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
descAssocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
descAssocsIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWM :: WaveletMatrix -> RawWaveletMatrix
xDictWM :: WaveletMatrix -> Vector Int
rawWM :: RawWaveletMatrix
xDictWM :: Vector Int
..} Int
l Int
r = RawWaveletMatrix -> Int -> Int -> (Int -> Int) -> [(Int, Int)]
Rwm.descAssocsInWith RawWaveletMatrix
rawWM Int
l Int
r (Vector Int
xDictWM VG.!)