| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
AtCoder.Extra.Bisect
Description
Bisection methods and binary search functions. They partition a half-open interval \([l, r)\) into two and return either the left or the right point of the boundary.
Y Y Y Y Y N N N N N Y: user predicate holds
--------* *---------> X N: user predicate does not hold
L R L, R: left, right point of the boundary
Example
Perform index compression:
>>>import AtCoder.Extra.Bisect>>>import Data.Vector.Algorithms.Intro qualified as VAI>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList ([0, 20, 10, 40, 30] :: [Int])>>>let dict = VU.uniq $ VU.modify VAI.sort xs>>>VU.map (lowerBound dict) xs[0,2,1,4,3]
Since: 1.3.0.0
Synopsis
- lowerBound :: (HasCallStack, Vector v a, Ord a) => v a -> a -> Int
- lowerBoundIn :: (HasCallStack, Vector v a, Ord a) => Int -> Int -> v a -> a -> Int
- upperBound :: (HasCallStack, Vector v a, Ord a) => v a -> a -> Int
- upperBoundIn :: (HasCallStack, Vector v a, Ord a) => Int -> Int -> v a -> a -> Int
- maxRight :: HasCallStack => Int -> Int -> (Int -> Bool) -> Int
- maxRightM :: (HasCallStack, Monad m) => Int -> Int -> (Int -> m Bool) -> m Int
- minLeft :: HasCallStack => Int -> Int -> (Int -> Bool) -> Int
- minLeftM :: (HasCallStack, Monad m) => Int -> Int -> (Int -> m Bool) -> m Int
C++-like binary search
lowerBound :: (HasCallStack, Vector v a, Ord a) => v a -> a -> Int Source #
\(O(\log n)\) Returns the maximum \(r\) where \(x \lt x_i\) holds for \(i \in [0, r)\).
Y Y Y Y Y N N N N N Y: (< x0)
--------- *---------> X N: (>= x0)
R R: the right boundary point returned
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [1, 1, 2, 2, 4, 4]>>>lowerBound xs 10
>>>lowerBound xs 22
>>>lowerBound xs 34
>>>lowerBound xs 44
Out of range values also return some index:
>>>lowerBound xs 00
>>>lowerBound xs 56
Since: 1.3.0.0
lowerBoundIn :: (HasCallStack, Vector v a, Ord a) => Int -> Int -> v a -> a -> Int Source #
\(O(\log n)\) Computes the lowerBound for a slice of a vector within the interval \([l, r)\).
- The user predicate evaluates indices in \([l, r)\).
Constraints
- (0 le l lt n)
- (-1 le r le n)
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [10, 10, 20, 20, 40, 40]>>>-- *---*---*>>>lowerBoundIn 2 5 xs 102
>>>lowerBoundIn 2 5 xs 202
>>>lowerBoundIn 2 5 xs 304
>>>lowerBoundIn 2 5 xs 404
>>>lowerBoundIn 2 5 xs 505
Since: 1.3.0.0
upperBound :: (HasCallStack, Vector v a, Ord a) => v a -> a -> Int Source #
\(O(\log n)\) Returns the maximum \(r\) where \(x \le x_i\) holds for \(i \in [0, r)\).
Y Y Y Y Y N N N N N Y: (<= x0)
--------- *---------> X N: (> x0)
R R: the right boundary point returned
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [10, 10, 20, 20, 40, 40]>>>upperBound xs 102
>>>upperBound xs 204
>>>upperBound xs 304
>>>upperBound xs 394
Out of range values:
>>>upperBound xs 00
>>>upperBound xs 406
Since: 1.3.0.0
upperBoundIn :: (HasCallStack, Vector v a, Ord a) => Int -> Int -> v a -> a -> Int Source #
\(O(\log n)\) Computes the upperBound for a slice of a vector within the interval \([l, r)\).
- The user predicate evaluates indices in \([l, r)\).
- The interval \([l, r)\) is silently clamped to ensure it remains within the bounds \([0, n)\).
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [10, 10, 20, 20, 40, 40]>>>-- *---*---*>>>upperBoundIn 2 5 xs 02
>>>upperBoundIn 2 5 xs 102
>>>upperBoundIn 2 5 xs 204
>>>upperBoundIn 2 5 xs 304
>>>upperBoundIn 2 5 xs 405
>>>upperBoundIn 2 5 xs 505
Since: 1.3.0.0
Generic bisection method
Arguments
| :: HasCallStack | |
| => Int | \(l\) |
| -> Int | \(r\) |
| -> (Int -> Bool) | \(p\) |
| -> Int | Maximum \(r'\) where \(p\) holds for \([l, r')\). |
\(O(\log n)\) Applies the bisection method on a half-open interval \([l, r)\) and returns the right boundary point.
Y Y Y Y Y N N N N N Y: user predicate holds
--------- *---------> X N: user predicate does not hold
R R: the right boundary point returned
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [10, 10, 20, 20, 30, 30]>>>let n = VU.length xs>>>maxRight 0 n ((<= 20) . (xs VU.!))4
>>>maxRight 0 n ((<= 0) . (xs VU.!))0
>>>maxRight 0 n ((<= 100) . (xs VU.!))6
>>>maxRight 0 3 ((<= 20) . (xs VU.!))3
Since: 1.3.0.0
maxRightM :: (HasCallStack, Monad m) => Int -> Int -> (Int -> m Bool) -> m Int Source #
\(O(\log n)\) Monadic variant of maxRight.
Since: 1.3.0.0
Arguments
| :: HasCallStack | |
| => Int | \(l\) |
| -> Int | \(r\) |
| -> (Int -> Bool) | \(p\) |
| -> Int | Minimum \(l'\) where \(p\) holds for \([l', r)\) |
\(O(\log n)\) Applies the bisection method on a half-open interval \([l, r)\) and returns the left boundary point.
N N N N N Y Y Y Y Y Y: user predicate holds
--------* ----------> X N: user predicate does not hold
L L: the left boundary point returned
Example
>>>import Data.Vector.Unboxed qualified as VU>>>let xs = VU.fromList [10, 10, 20, 20, 30, 30]>>>let n = VU.length xs>>>minLeft 0 n ((>= 20) . (xs VU.!))2
>>>minLeft 0 n ((>= 0) . (xs VU.!))0
>>>minLeft 0 n ((>= 100) . (xs VU.!))6
Since: 1.3.0.0