{-# 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.Vector.Algorithms.Intro qualified as VAI
import Data.Vector.Generic qualified as VG
import Data.Vector.Unboxed qualified as VU
import GHC.Stack (HasCallStack)
data WaveletMatrix = WaveletMatrix
{
WaveletMatrix -> RawWaveletMatrix
rawWm :: !Rwm.RawWaveletMatrix,
WaveletMatrix -> Vector Int
yDictWm :: !(VU.Vector Int)
}
{-# INLINE build #-}
build :: VU.Vector Int -> WaveletMatrix
build :: Vector Int -> WaveletMatrix
build Vector Int
ys =
let !yDictWm :: Vector Int
yDictWm = 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 (Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Int
lowerBound Vector Int
yDictWm) 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
yDictWm :: Vector Int
yDictWm :: Vector Int
rawWm :: RawWaveletMatrix
..}
{-# INLINE access #-}
access :: WaveletMatrix -> Int -> Maybe Int
access :: WaveletMatrix -> Int -> Maybe Int
access WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
i = (Vector Int
yDictWm 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)
{-# INLINEABLE rankBetween #-}
rankBetween ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Int ->
Int
rankBetween :: WaveletMatrix -> Int -> Int -> Int -> Int -> Int
rankBetween WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: 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' = Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Int
lowerBound Vector Int
yDictWm Int
y1
y2' :: Int
y2' = Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Int
lowerBound Vector Int
yDictWm Int
y2
{-# 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
{-# INLINEABLE selectKth #-}
selectKth ::
WaveletMatrix ->
Int ->
Int ->
Maybe Int
selectKth :: WaveletMatrix -> Int -> Int -> Maybe Int
selectKth WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
k Int
y = do
let !i :: Int
i = Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Int
lowerBound Vector Int
yDictWm Int
y
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
yDictWm
let !y' :: Int
y' = Vector Int
yDictWm 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 = HasCallStack =>
WaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
WaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
selectKthIn WaveletMatrix
wm Int
l Int
r Int
0
{-# INLINEABLE selectKthIn #-}
selectKthIn ::
(HasCallStack) =>
WaveletMatrix ->
Int ->
Int ->
Int ->
Int ->
Maybe Int
selectKthIn :: HasCallStack =>
WaveletMatrix -> Int -> Int -> Int -> Int -> Maybe Int
selectKthIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
l Int
r Int
k Int
y = do
let !i :: Int
i = Vector Int -> Int -> Int
forall (v :: * -> *) a.
(HasCallStack, Vector v a, Ord a) =>
v a -> a -> Int
lowerBound Vector Int
yDictWm Int
y
Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Maybe ()) -> Bool -> Maybe ()
forall a b. (a -> b) -> a -> b
$ Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Vector Int -> Int
forall (v :: * -> *) a. Vector v a => v a -> Int
VG.length Vector Int
yDictWm
let !y' :: Int
y' = Vector Int
yDictWm 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
{-# INLINEABLE kthLargestIn #-}
kthLargestIn ::
(HasCallStack) =>
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
kthLargestIn :: HasCallStack => WaveletMatrix -> Int -> Int -> Int -> Maybe Int
kthLargestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: 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
yDictWm 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
{-# INLINEABLE 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
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: 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
yDictWm 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
{-# INLINEABLE kthSmallestIn #-}
kthSmallestIn ::
WaveletMatrix ->
Int ->
Int ->
Int ->
Maybe Int
kthSmallestIn :: WaveletMatrix -> Int -> Int -> Int -> Maybe Int
kthSmallestIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: 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
yDictWm 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
{-# INLINEABLE 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
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: 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
yDictWm 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
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
l Int
r Int
k =
Vector Int
yDictWm 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
{-# INLINEABLE 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)
{-# INLINEABLE 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
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
l Int
r = RawWaveletMatrix -> Int -> Int -> (Int -> Int) -> [(Int, Int)]
Rwm.assocsWith RawWaveletMatrix
rawWm Int
l Int
r (Vector Int
yDictWm VG.!)
{-# INLINE descAssocsIn #-}
descAssocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
descAssocsIn :: WaveletMatrix -> Int -> Int -> [(Int, Int)]
descAssocsIn WaveletMatrix {Vector Int
RawWaveletMatrix
rawWm :: WaveletMatrix -> RawWaveletMatrix
yDictWm :: WaveletMatrix -> Vector Int
rawWm :: RawWaveletMatrix
yDictWm :: Vector Int
..} Int
l Int
r = RawWaveletMatrix -> Int -> Int -> (Int -> Int) -> [(Int, Int)]
Rwm.descAssocsInWith RawWaveletMatrix
rawWm Int
l Int
r (Vector Int
yDictWm VG.!)