packages feed

ac-library-hs 1.4.0.0 → 1.5.0.0

raw patch · 49 files changed

+333/−248 lines, 49 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- AtCoder.Extra.Graph: bfs01 :: (HasCallStack, Ix0 i, Unbox i) => Bounds0 i -> (i -> Vector (i, Int)) -> Int -> Vector (i, Int) -> Vector Int
+ AtCoder.Extra.Graph: bfs01 :: (HasCallStack, Ix0 i, Unbox i) => Bounds0 i -> Int -> (i -> Vector (i, Int)) -> Vector (i, Int) -> Vector Int
- AtCoder.Extra.Graph: dijkstra :: (HasCallStack, Ix0 i, Ord i, Unbox i, Num w, Ord w, Unbox w) => Bounds0 i -> (i -> Vector (i, w)) -> Int -> w -> Vector (i, w) -> Vector w
+ AtCoder.Extra.Graph: dijkstra :: (HasCallStack, Ix0 i, Ord i, Unbox i, Num w, Ord w, Unbox w) => Bounds0 i -> Int -> (i -> Vector (i, w)) -> w -> Vector (i, w) -> Vector w
- AtCoder.Extra.Graph: trackingBfs01 :: (HasCallStack, Ix0 i, Unbox i) => Bounds0 i -> (i -> Vector (i, Int)) -> Int -> Vector (i, Int) -> (Vector Int, Vector Int)
+ AtCoder.Extra.Graph: trackingBfs01 :: (HasCallStack, Ix0 i, Unbox i) => Bounds0 i -> Int -> (i -> Vector (i, Int)) -> Vector (i, Int) -> (Vector Int, Vector Int)
- AtCoder.Extra.Graph: trackingDijkstra :: (HasCallStack, Ix0 i, Ord i, Unbox i, Num w, Ord w, Unbox w) => Bounds0 i -> (i -> Vector (i, w)) -> Int -> w -> Vector (i, w) -> (Vector w, Vector Int)
+ AtCoder.Extra.Graph: trackingDijkstra :: (HasCallStack, Ix0 i, Ord i, Unbox i, Num w, Ord w, Unbox w) => Bounds0 i -> Int -> (i -> Vector (i, w)) -> w -> Vector (i, w) -> (Vector w, Vector Int)

Files

CHANGELOG.md view
@@ -1,9 +1,14 @@ # Revision history for acl-hs +## 1.5.0.0 -- May 2025++- Changed the parameter orders of `bfs01` and `dijkstra` in `AtCoder.Extra.Graph`.+- Fixed `Hld.new` to have `headHld` of `[0]`, not `[-1]`.+ ## 1.4.0.0 -- May 2025 -- Added cycle detection functions to `AtCoder.Extra.Graph`-- Fixed the exteremely slow `Internal.GrowVec` functions with `{-# INLINE #-}`+- Added cycle detection functions to `AtCoder.Extra.Graph`.+- Fixed the exteremely slow `Internal.GrowVec` functions with `{-# INLINE #-}`. - Changed `AtCoder.Extra.Pdsu.merge` to return new representative. - Fixed `AtCoder.Extra.Hld.jump` to return `Nothing` for `k < 0`. 
README.md view
@@ -2,7 +2,7 @@  Haskell port of [ac-library](https://github.com/atcoder/ac-library), a library for competitive programming on [AtCoder](https://atcoder.jp/). -The `main` branch is the version avaiable on AtCoder. See `dev` branch for upcoming updates.+The `main` branch is the version avaiable on AtCoder (+ documentation fixes). See `dev` branch for upcoming updates.  ## Notes 
ac-library-hs.cabal view
@@ -4,7 +4,7 @@ -- PVP summary:  +-+------- breaking API changes --               | | +----- non-breaking API additions --               | | | +--- code changes with no API change-version:         1.4.0.0+version:         1.5.0.0 synopsis:        Data structures and algorithms description:   Haskell port of [ac-library](https://github.com/atcoder/ac-library), a library for competitive@@ -151,6 +151,7 @@     Tests.Extra.DynSparseSegTree.Persistent     Tests.Extra.Graph     Tests.Extra.HashMap+    Tests.Extra.Hld     Tests.Extra.IntervalMap     Tests.Extra.IntMap     Tests.Extra.IntSet@@ -192,7 +193,6 @@     Tests.String     Tests.TwoSat     Tests.Util-    Util    type:           exitcode-stdio-1.0   hs-source-dirs: test
src/AtCoder/Convolution.hs view
@@ -64,7 +64,7 @@ import GHC.TypeNats (natVal')  -- NOTE(pref): Inlining `convolution` functions makes the compile time extremely too slow, while it--- surely makes beter runtime performance (#51).+-- surely makes better runtime performance (#51).  -- | Calculates the convolution in \(\bmod m\) for a vector of `ACIM.ModInt`. It returns an empty -- array if at least one of \(a\) and \(b\) are empty.
src/AtCoder/Dsu.hs view
@@ -80,7 +80,7 @@ import Data.Vector.Unboxed.Mutable qualified as VUM import GHC.Stack (HasCallStack) --- | A disjoint set union. Akso known as Union-Find tree.+-- | A disjoint set union. Also known as Union-Find tree. -- -- @since 1.0.0.0 data Dsu s = Dsu
src/AtCoder/Extra/Bisect.hs view
@@ -6,7 +6,7 @@ -- @ -- 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+--         L R              L, R: left and right points of the boundary -- @ -- -- ==== __Example__@@ -64,7 +64,6 @@ -- >>> lowerBound xs 4 -- 4 ----- -- >>> lowerBound xs 5 -- 6 --@@ -256,7 +255,7 @@   Int minLeft l r p = runIdentity $ minLeftM l r (pure . p) --- | \(O(\log n)\) Monadic variant of `maxRight`.+-- | \(O(\log n)\) Monadic variant of `minLeft`. -- -- @since 1.3.0.0 {-# INLINE minLeftM #-}
src/AtCoder/Extra/DynLazySegTree.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-}  -- | A dynamic, lazily propagated segment tree that covers a half-open interval \([l_0, r_0)\).--- Nodes are instantinated as needed, with the required capacity being /approximately/ \(4q \log_2 L\),+-- Nodes are instantiated as needed, with the required capacity being /approximately/ \(4q \log_2 L\), -- where \(q\) is the number of mutable operations and \(L\) is the length of the interval. -- -- ==== __Example__@@ -312,7 +312,7 @@ maxRightM dst root f = do   Raw.maxRightM dst root f --- | \(O(\log L)\) Claers all the nodes from the storage.+-- | \(O(\log L)\) Clears all the nodes from the storage. -- -- @since 1.2.2.0 {-# INLINE clear #-}
src/AtCoder/Extra/DynLazySegTree/Persistent.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-}  -- | A dynamic, persistent, lazily propagated segment tree that covers a half-open interval--- \([l_0, r_0)\). Nodes are instantinated as needed, with the required capacity being+-- \([l_0, r_0)\). Nodes are instantiated as needed, with the required capacity being -- /approximately/ \(8q \log_2 L\), where \(q\) is the number of mutable operations and \(L\) is the -- length of the interval. --@@ -294,7 +294,7 @@ maxRightM dst root f = do   Raw.maxRightM dst root f --- | \(O(\log L)\) Claers all the nodes from the storage.+-- | \(O(\log L)\) Clears all the nodes from the storage. -- -- @since 1.2.2.0 {-# INLINE clear #-}
src/AtCoder/Extra/DynSegTree.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-}  -- | A dynamic segment tree that covers a half-open interval \([l_0, r_0)\). Nodes are--- instantinated as needed, with the required capacity being /approximately/ \(2q \log_2 L\), where+-- instantiated as needed, with the required capacity being /approximately/ \(2q \log_2 L\), where -- \(q\) is the number of mutable operations and \(L\) is the length of the interval. -- -- ==== __Example__@@ -223,7 +223,7 @@ maxRightM dst root f = do   Raw.maxRightM dst root f --- | \(O(\log L)\) Claers all the nodes from the storage.+-- | \(O(\log L)\) Clears all the nodes from the storage. -- -- @since 1.2.2.0 {-# INLINE clear #-}
src/AtCoder/Extra/DynSegTree/Persistent.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-}  -- | A dynamic, persistent segment tree that covers a half-open interval \([l_0, r_0)\). Nodes are--- instantinated as needed, with the required capacity being /approximately/ \(4q \log_2 L\), where+-- instantiated as needed, with the required capacity being /approximately/ \(4q \log_2 L\), where -- \(q\) is the number of mutable operations and \(L\) is the length of the interval. -- -- ==== __Example__@@ -215,7 +215,7 @@ maxRightM dst root f = do   Raw.maxRightM dst root f --- | \(O(\log L)\) Claers all the nodes from the storage.+-- | \(O(\log L)\) Clears all the nodes from the storage. -- -- @since 1.2.2.0 {-# INLINE clear #-}
src/AtCoder/Extra/DynSegTree/Raw.hs view
@@ -47,8 +47,8 @@ import GHC.Stack (HasCallStack) import Prelude hiding (read) --- | A dynamic segment tree that covers a half-open interval \([l_0, r_0)\). Is is dynamic in that--- the nodes are instantinated as needed.+-- | A dynamic segment tree that covers a half-open interval \([l_0, r_0)\). It is dynamic in that+-- the nodes are instantiated as needed. -- -- @since 1.2.1.0 data DynSegTree s a = DynSegTree
src/AtCoder/Extra/Graph.hs view
@@ -242,8 +242,7 @@  -- TODO: is this minimum cycle? --- | \(O(n + m)\) Given a directed graph, finds a minimal cycle and returns a vector of vertices and--- a vector of @(vertices, csrEdgeIndices)@.+-- | \(O(n + m)\) Given a directed graph, finds a minimal cycle and returns @(vertices, csrEdgeIndices)@. -- -- ==== __Example__ --@@ -346,9 +345,9 @@     then pure Nothing     else pure $ Just (vs', es') --- | \(O(n + m)\) Given an undirected graph, finds a minimal cycle and returns a vector of vertices--- a vector of @(vertices, csrEdgeIndices)@. A single edge index does not make much sense for an--- undirected graph, so map back to the original edge index manually if needed.+-- | \(O(n + m)\) Given an undirected graph, finds a minimal cycle and returns @(vertices, csrEdgeIndices)@.+-- A single edge index does not make much sense for an undirected graph, so map back to the original+-- edge index manually if needed. -- -- ==== Constraints -- - The graph must be created with `swapDupe` or `swapDupe'`. Otherwise the returned edge indices@@ -720,7 +719,7 @@   Int ->   -- | \(g\): Graph function, typically @'adj' gr@.   (Int -> VU.Vector Int) ->-  -- | Graph that represents a block-cut tree, where super vertices \((n \ge n)\) represent each+  -- | Graph that represents a block-cut tree, where super vertices \((v \ge n)\) represent each   -- biconnected component.   Csr () blockCut n gr = runST $ do@@ -792,7 +791,7 @@   n' <- VGM.unsafeRead next 0   Csr.build' n' <$> B.unsafeFreeze edges --- | \(O(n + m)\) Returns [blocks (biconnected comopnents)](https://en.wikipedia.org/wiki/Biconnected_component)+-- | \(O(n + m)\) Returns [blocks (biconnected components)](https://en.wikipedia.org/wiki/Biconnected_component) -- of the graph. -- -- ==== __Example__@@ -945,62 +944,74 @@  -- | \(O(n + m)\) Opinionated 01-BFS that returns a distance array. --+-- Unreachable vertices are given distance of `-1`. Note that the third argument is the capacity of+-- deque, not distance of unreachable vertices.+--+-- ==== Constraints+-- - \(\marhrm{capacity} \ge 0\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU -- >>> let es = VU.fromList [(0, 1, 10 :: Int), (0, 2, 0), (2, 1, 1)] -- >>> let gr = Gr.build 4 es--- >>> let capacity = 10--- >>> Gr.bfs01 4 (Gr.adjW gr) capacity (VU.singleton (0, 0))+-- >>> let capacity = VU.length es+-- >>> Gr.bfs01 4 capacity (Gr.adjW gr) (VU.singleton (0, 0)) -- [0,1,0,-1] ----- @since 1.2.4.0+-- @since 1.5.0.0 {-# INLINE bfs01 #-} bfs01 ::   forall i.   (HasCallStack, Ix0 i, VU.Unbox i) =>-  -- | Zero-based index boundary.+  -- | Zero-based vertex boundary. It's \(n\) if the graph is one-dimensional.   Bounds0 i ->+  -- | Capacity of deque, often the number of edges \(m\).+  Int ->   -- | Graph function that takes the vertexand returns adjacent vertices with edge weights, where   -- \(w > 0\).   (i -> VU.Vector (i, Int)) ->-  -- | Capacity of deque, often the number of edges \(m\).-  Int ->   -- | Weighted source vertices.   VU.Vector (i, Int) ->   -- | Distance array in one-dimensional index. Unreachable vertices are assigned distance of @-1@.   VU.Vector Int-bfs01 !bnd0 !gr !capacity !sources =-  let (!dist, !_) = bfs01Impl False bnd0 gr capacity sources+bfs01 !bnd0 !capacity !gr !sources =+  let (!dist, !_) = bfs01Impl False bnd0 capacity gr sources    in dist  -- | \(O(n + m)\) Opinionated 01-BFS that returns a distance array and a predecessor array. --+-- Unreachable vertices are given distance of `-1`. Note that the third argument is the capacity of+-- deque, not distance of unreachable vertices.+--+-- ==== Constraints+-- - \(\marhrm{capacity} \ge 0\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU -- >>> let es = VU.fromList [(0, 1, 10 :: Int), (0, 2, 0), (2, 1, 1)] -- >>> let gr = Gr.build 4 es--- >>> let capacity = 10--- >>> let (!dist, !prev) = Gr.trackingBfs01 4 (Gr.adjW gr) capacity (VU.singleton (0, 0))+-- >>> let capacity = VU.length es+-- >>> let (!dist, !prev) = Gr.trackingBfs01 4 capacity (Gr.adjW gr) (VU.singleton (0, 0)) -- >>> dist -- [0,1,0,-1] -- -- >>> Gr.constructPathFromRoot prev 1 -- [0,2,1] ----- @since 1.2.4.0+-- @since 1.5.0.0 {-# INLINE trackingBfs01 #-} trackingBfs01 ::   forall i.   (HasCallStack, Ix0 i, VU.Unbox i) =>-  -- | Zero-based index boundary.+  -- | Zero-based vertex boundary. It's \(n\) if the graph is one-dimensional.   Bounds0 i ->+  -- | Capacity of deque, often the number of edges \(m\).+  Int ->   -- | Graph function that takes the vertex and returns adjacent vertices with edge weights, where   -- \(w > 0\).   (i -> VU.Vector (i, Int)) ->-  -- | Capacity of deque, often the number of edges \(m\).-  Int ->   -- | Weighted source vertices.   VU.Vector (i, Int) ->   -- | A tuple of (distance array in one-dimensional index, predecessor array). Unreachable vertices@@ -1014,11 +1025,11 @@   (HasCallStack, Ix0 i, VU.Unbox i) =>   Bool ->   Bounds0 i ->-  (i -> VU.Vector (i, Int)) ->   Int ->+  (i -> VU.Vector (i, Int)) ->   VU.Vector (i, Int) ->   (VU.Vector Int, VU.Vector Int)-bfs01Impl !trackPrev !bnd0 !gr !capacity !sources+bfs01Impl !trackPrev !bnd0 !capacity !gr !sources   | VU.null sources && trackPrev = (VU.replicate nVerts (-1), VU.replicate nVerts (-1))   | VU.null sources = (VU.replicate nVerts (-1), VU.replicate 0 (-1))   | otherwise = runST $ do@@ -1029,7 +1040,8 @@           else VUM.replicate @_ @Int 0 (-1)       -- NOTE: Just like Dijkstra, we need capacity of `m`, as the first appearance of a vertex is not       -- always with minimum distance.-      deque <- Q.newDeque @_ @(i, Int) capacity+      -- NOTE: Ensure minimum capacity of |sources| (too conservative?)+      deque <- Q.newDeque @_ @(i, Int) $ capacity + VU.length sources        -- set source values       VU.forM_ sources $ \(!src, !w0) -> do@@ -1072,65 +1084,71 @@  -- | \(O((n + m) \log n)\) Dijkstra's algorithm that returns a distance array. --+-- ==== Constraints+-- - \(\mathrm{capacity} \ge 0\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU -- >>> let es = VU.fromList [(0, 1, 10 :: Int), (1, 2, 20), (2, 3, 1), (1, 3, 40), (4, 3, 0)] -- >>> let gr = Gr.build 5 es--- >>> let capacity = 10--- >>> Gr.dijkstra 5 (Gr.adjW gr) capacity (-1) (VU.singleton (0, 0))+-- >>> let capacity = VU.length es+-- >>> Gr.dijkstra 5 capacity (Gr.adjW gr) (-1) (VU.singleton (0, 0)) -- [0,10,30,31,-1] ----- @since 1.2.4.0+-- @since 1.5.0.0 {-# INLINE dijkstra #-} dijkstra ::   forall i w.   (HasCallStack, Ix0 i, Ord i, VU.Unbox i, Num w, Ord w, VU.Unbox w) =>-  -- | Zero-based vertex boundary.+  -- | Zero-based vertex boundary. It's \(n\) if the graph is one-dimensional.   Bounds0 i ->+  -- | Capacity of the heap, often the number of edges \(m\).+  Int ->   -- | Graph function that takes a vertex and returns adjacent vertices with edge weights, where   -- \(w \ge 0\).   (i -> VU.Vector (i, w)) ->-  -- | Capacity of the heap, often the number of edges \(m\).-  Int ->   -- | Distance assignment for unreachable vertices.   w ->   -- | Source vertices with initial weights.   VU.Vector (i, w) ->   -- | Distance array in one-dimensional index.   VU.Vector w-dijkstra !bnd0 !gr !capacity !undefW !sources =-  let (!dist, !_) = dijkstraImpl False bnd0 gr capacity undefW sources+dijkstra !bnd0 !capacity !gr !undefW !sources =+  let (!dist, !_) = dijkstraImpl False bnd0 capacity gr undefW sources    in dist  -- | \(O((n + m) \log n)\) Dijkstra's algorithm that returns a distance array and a predecessor -- array. --+-- ==== Constraints+-- - \(\mathrm{capacity} \ge 0\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU -- >>> let es = VU.fromList [(0, 1, 10 :: Int), (1, 2, 20), (2, 3, 1), (1, 3, 40), (4, 3, 0)] -- >>> let gr = Gr.build 5 es--- >>> let capacity = 10--- >>> let (!dist, !prev) = Gr.trackingDijkstra 5 (Gr.adjW gr) capacity (-1) (VU.singleton (0, 0))+-- >>> let capacity = VU.length es+-- >>> let (!dist, !prev) = Gr.trackingDijkstra 5 capacity (Gr.adjW gr) (-1) (VU.singleton (0, 0)) -- >>> dist -- [0,10,30,31,-1] -- -- >>> Gr.constructPathFromRoot prev 3 -- [0,1,2,3] ----- @since 1.2.4.0+-- @since 1.5.0.0 {-# INLINE trackingDijkstra #-} trackingDijkstra ::   forall i w.   (HasCallStack, Ix0 i, Ord i, VU.Unbox i, Num w, Ord w, VU.Unbox w) =>-  -- | Zero-based vertex boundary.+  -- | Zero-based vertex boundary. It's \(n\) if the graph is one-dimensional.   Bounds0 i ->+  -- | Capacity of the heap, often the number of edges \(m\).+  Int ->   -- | Graph function that takes a vertex and returns adjacent vertices with edge weights, where   -- \(w \ge 0\).   (i -> VU.Vector (i, w)) ->-  -- | Capacity of the heap, often the number of edges \(m\).-  Int ->   -- | Distance assignment for unreachable vertices.   w ->   -- | Source vertices with initial weights.@@ -1145,18 +1163,19 @@   (HasCallStack, Ix0 i, Ord i, VU.Unbox i, Num w, Ord w, VU.Unbox w) =>   Bool ->   Bounds0 i ->-  (i -> VU.Vector (i, w)) ->   Int ->+  (i -> VU.Vector (i, w)) ->   w ->   VU.Vector (i, w) ->   (VU.Vector w, VU.Vector Int)-dijkstraImpl !trackPrev !bnd0 !gr !capacity !undefW !sources+dijkstraImpl !trackPrev !bnd0 !capacity !gr !undefW !sources   | VU.null sources && trackPrev = (VU.replicate nVerts undefW, VU.replicate nVerts (-1))   | VU.null sources = (VU.replicate nVerts undefW, VU.replicate 0 (-1))   | otherwise = runST $ do       !dist <- VUM.replicate @_ @w nVerts undefW       -- REMARK: (w, i) for sort by width-      !heap <- MH.new @_ @(w, i) capacity+      -- REMARK: We need least capacity of |source|+      !heap <- MH.new @_ @(w, i) $ capacity + VU.length sources       !prev <-         if trackPrev           then VUM.replicate @_ @Int nVerts (-1)@@ -1427,6 +1446,9 @@ -- - There's a negative loop if there's any vertex \(v\) where @m VU.! (`index0` (n, n) (v, v))@ -- is negative. --+-- ==== Constraints+-- - \(n \ge 1\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU@@ -1465,6 +1487,9 @@ -- - There's a negative loop if there's any vertex \(v\) where @m VU.! (`index0` (n, n) (v, v))@ -- is negative. --+-- ==== Constraints+-- - \(n \ge 1\)+-- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr -- >>> import Data.Vector.Unboxed qualified as VU@@ -1552,6 +1577,9 @@  -- | \(O(n^2)\) Updates distance matrix of Floyd–Warshall on edge weight change or new edge addition. --+-- ==== Constraints+-- - \(n \ge 1\)+-- -- @since 1.2.4.0 {-# INLINE updateEdgeFloydWarshall #-} updateEdgeFloydWarshall ::@@ -1577,6 +1605,9 @@   stToPrim $ updateEdgeFloydWarshallST False mat prev nVerts undefW a b w  -- | \(O(n^2)\) Updates distance matrix of Floyd–Warshall on edge weight chaneg or new edge addition.+--+-- ==== Constraints+-- - \(n \ge 1\) -- -- @since 1.2.4.0 {-# INLINE updateEdgeTrackingFloydWarshall #-}
src/AtCoder/Extra/HashMap.hs view
@@ -17,7 +17,7 @@ -- >>> import AtCoder.Extra.HashMap qualified as HM -- >>> hm <- HM.new @_ @Int 10 ----- `insert`, `lookup` and other functions are available in \(O(1)\) in averaged:+-- `insert`, `lookup` and other functions are available in \(O(1)\) on average: -- -- >>> HM.insert hm 0 100 -- >>> HM.insert hm 10 101
src/AtCoder/Extra/Ix0.hs view
@@ -3,18 +3,18 @@ -- | Opinionated zero-based \(n\)-dimensional index and their bounds. module AtCoder.Extra.Ix0 where --- | Zero-based \(n\)-dimensional bounds: \([0, d_0) \times [0, d_1) \times .. \times [0, d_{n - 1})\).+-- | Zero-based \(n\)-dimensional bounds: \([0, d_0) \times [0, d_1) \times \cdots \times [0, d_{n - 1})\). type Bounds0 i = i  -- | Zero-based \(n\)-dimensional index. class Ix0 i where-  -- | Returns the size of the bounds: \(\Pi_i d_i\).+  -- | Returns the size of the bounds: \(\prod_i d_i\).   rangeSize0 :: Bounds0 i -> Int -  -- | Returns zero-based one dimensional index, __without__ running boundary check.+  -- | Returns zero-based one-dimensional index, __without__ running boundary check.   index0 :: Bounds0 i -> i -> Int -  -- | Returns whether an index is contained in a bounds.+  -- | Returns whether an index is contained in bounds.   inRange0 :: Bounds0 i -> i -> Bool  instance Ix0 Int where@@ -59,7 +59,7 @@  instance Ix0 (Int, Int, Int, Int, Int, Int) where   {-# INLINE rangeSize0 #-}-  rangeSize0 (!d6, !d5, !d4, !d3, !d2, !d1) = d6 + d5 * d4 * d3 * d2 * d1+  rangeSize0 (!d6, !d5, !d4, !d3, !d2, !d1) = d6 * d5 * d4 * d3 * d2 * d1   {-# INLINE index0 #-}   index0 (!_, !d5, !d4, !d3, !d2, !d1) (!x6, !x5, !x4, !x3, !x2, !x1) = ((((x6 * d5 + x5) * d4 + x4) * d3 + x3) * d2 + x2) * d1 + x1   {-# INLINE inRange0 #-}
src/AtCoder/Extra/Mo.hs view
@@ -1,5 +1,5 @@ -- | Mo's algorithm for handling \([l, r)\) offline queries in \(O((n + q) \sqrt n f)\) time--- complecity, where \(n\) is the length of index, \(q\) is the number of queries and \(f\) is the+-- complexity, where \(n\) is the length of index, \(q\) is the number of queries and \(f\) is the -- time for processing element addition or deletion. Due to the high time complexity, it is -- recommended to choose an efficient data structure such as Fenwick Tree for query processing. --
src/AtCoder/Extra/ModInt64.hs view
@@ -110,9 +110,9 @@ unsafeNew :: (KnownNat a) => Word64 -> ModInt64 a unsafeNew = ModInt64 --- | \(O(1)\) Retrieve the mod from a `ModInt64` object.+-- | \(O(1)\) Retrieve the modulus from a `ModInt64` object. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.2.6.0@@ -120,9 +120,9 @@ modulus :: forall a. (KnownNat a) => ModInt64 a -> Int modulus _ = fromIntegral (natVal' (proxy# @a)) --- | \(O(1)\) Returns the internal value in `Int`.+-- | \(O(1)\) Returns the internal value as an `Int`. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.2.6.0@@ -130,9 +130,9 @@ val :: forall a. (KnownNat a) => ModInt64 a -> Int val = fromIntegral . val64 --- | \(O(1)\) Returns the internal value in `Word64`.+-- | \(O(1)\) Returns the internal value as a `Word64`. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.2.6.0
src/AtCoder/Extra/Monoid/Mat2x2.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE TypeFamilies #-}  -- | Monoid action \(f: x \rightarrow ax + b\). Less efficient than @Affine1@, but is compatible--- with inverse opereations.+-- with inverse operations. -- -- @since 1.1.0.0 module AtCoder.Extra.Monoid.Mat2x2@@ -136,7 +136,7 @@     !a21' = f a21     !a22' = f a22 --- | \(O(1)\) Returns the determinan of the matrix.+-- | \(O(1)\) Returns the determinant of the matrix. -- -- @since 1.1.0.0 {-# INLINE det #-}@@ -146,7 +146,7 @@ -- | \(O(1)\) Returns the inverse matrix, based on `Fractional` instance (mainly for @ModInt@). -- -- ==== Constraints--- - The determinant (`det`) of the matrix must be non-zero, otherwise an error is thrown.+-- - The determinant (`det`) of the matrix must be nonzero, otherwise an error is thrown. -- -- @since 1.1.0.0 {-# INLINE inv #-}
src/AtCoder/Extra/Monoid/RangeAdd.hs view
@@ -8,7 +8,7 @@   ( -- * RangeAdd     RangeAdd (..), -    -- * Constructor+    -- * Constructors     new,     unRangeAdd, 
src/AtCoder/Extra/Monoid/V2.hs view
@@ -4,7 +4,7 @@ -- | A monoid acted on by `Mat2x2` or `Affine1`, an affine transformation target. -- -- ==== As an `Affine1` action target--- Compared to `Sum`, `V2` hold the length in the second value.+-- Compared to `Sum`, `V2` holds the length in the second value. -- -- @since 1.1.0.0 module AtCoder.Extra.Monoid.V2
src/AtCoder/Extra/MultiSet.hs view
@@ -2,7 +2,7 @@ {-# LANGUAGE RecordWildCards #-}  -- | A fast, mutable multiset for `Int` keys backed by a @HashMap@. Most operations are performed--- in \(O(1)\) in average.+-- in \(O(1)\) on average. -- -- ==== Capacity limitation -- Access to each key creates a new entry. Note that entries cannot be invalidated due to the
src/AtCoder/Extra/Pdsu.hs view
@@ -3,12 +3,12 @@ -- original implementation: -- <https://qiita.com/drken/items/cce6fc5c579051e64fab> --- | A potentialized disjoint set union on a [group](https://en.wikipedia.org/wiki/Group_(mathematics\))+-- | A potentialized disjoint set union on a [group](https://en.wikipedia.org/wiki/Group_(mathematics)) -- under a differential constraint system. Each vertex \(v\) is assigned a potential value \(p(v)\), -- where representatives (`leader`) of each group have a potential value of `mempty`, and other -- vertices have potentials relative to their representative. ----- The group type is represented as a `Monoid` with a inverse operator, passed on `new`. This+-- The group type is represented as a `Monoid` with an inverse operator, passed on `new`. This -- approach avoids defining a separate typeclass for groups. -- -- ==== Invariant@@ -166,7 +166,7 @@ diff dsu v1 v2 = stToPrim $ diffST dsu v1 v2  -- | \(O(\alpha(n))\) Returns the potential of \(v_1\) relative to \(v_2\): \(p(v_1) \cdot p^{-1}(v_2)\)--- if the two vertices belong to the same group. Returns meaningless value if the two vertices are+-- if the two vertices belong to the same group. Returns a meaningless value if the two vertices are -- not connected. -- -- @since 1.1.0.0
src/AtCoder/Extra/Pool.hs view
@@ -50,7 +50,7 @@ import GHC.Stack (HasCallStack) import Prelude hiding (read) --- | Fixed-sized array for \(O(1)\) allocation and \(O(1)\) clearing after \(O(n)\) construction.+-- | Fixed-size array for \(O(1)\) allocation and \(O(1)\) clearing after \(O(n)\) construction. -- -- @since 1.2.0.0 data Pool s a = Pool@@ -166,9 +166,9 @@ -- | \(O(1)\) Writes to the \(k\)-th value. -- -- ==== Constraints+-- - \(0 \le i \lt n\) -- -- @since 1.2.0.0--- - \(0 \le i \lt n\) {-# INLINE write #-} write :: (PrimMonad m, VU.Unbox a) => Pool (PrimState m) a -> Index -> a -> m () write Pool {dataPool} !i !x = do
src/AtCoder/Extra/Semigroup/Matrix.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE RecordWildCards #-} --- | A simple HxW matrix backed by a vector, mainly for binary exponention.+-- | A simple HxW matrix backed by a vector, mainly for binary exponentiation. -- -- The matrix is a left semigroup action: \(m_2 (m_1 v) = (m_2 \circ m_1) v\). --@@ -65,7 +65,7 @@ import GHC.TypeNats (KnownNat, natVal') import Prelude hiding (map) --- | A simple HxW matrix backed by a vector, mainly for binary exponention.+-- | A simple HxW matrix backed by a vector, mainly for binary exponentiation. -- -- The matrix is a left semigroup action: \(m_2 (m_1 v) = (m_2 \circ m_1) v\). --
src/AtCoder/Extra/Tree.hs view
@@ -12,7 +12,7 @@      -- * Tree folding -    -- | These function are built around the three type parameters: \(w\), \(f\) and \(a\).+    -- | These functions are built around the three type parameters: \(w\), \(f\), and \(a\).     --     -- - \(w\): Edge weight.     -- - \(f\): Monoid action to a vertex value. These actions are created from vertex value \(a\)@@ -70,7 +70,7 @@       !w = VU.maximum bfs2    in ((from, to), w) --- | \(O(n + m)\) Returns the path longest path in a tree and the distance of it.+-- | \(O(n + m)\) Returns the longest path in a tree and the distance of it. -- -- ==== __Example__ -- >>> import AtCoder.Extra.Graph qualified as Gr@@ -101,9 +101,9 @@       !w = bfs2 VG.! to    in (Gr.constructPathFromRoot parents to, w) --- | \(O(m \log m)\) Kruscal's algorithm. Returns edge indices for building a minimum spanning tree.+-- | \(O(m \log m)\) Kruskal's algorithm. Returns edge indices for building a minimum spanning tree. ----- NOTE: The edges should not be duplicated: only one of \((u, v, w)\) or \((v, u w)\) is required+-- NOTE: The edges should not be duplicated: only one of \((u, v, w)\) or \((v, u, w)\) is required -- for each edge. -- -- ==== __Example__@@ -127,7 +127,7 @@ mst :: (Num w, Ord w, VU.Unbox w) => Int -> VU.Vector (Int, Int, w) -> (w, VU.Vector Bit, Gr.Csr w) mst = mstBy (comparing id) --- | \(O(m \log m)\) Kruscal's algorithm. Returns edge indices for building a minimum/maximum+-- | \(O(m \log m)\) Kruskal's algorithm. Returns edge indices for building a minimum/maximum -- spanning tree. -- -- NOTE: The edges should not be duplicated: only one of \((u, v, w)\) or \((v, u, w)\) is required
src/AtCoder/Extra/Tree/Hld.hs view
@@ -27,14 +27,14 @@ -- -- @ --  0==1==2==3==4==5==6==7==8==9     XX: VertexHld---     |        |                    ==: edges on the same semgent+--     |        |                    ==: edges on the same segment -- 14==13       10==11==12           |: edge between different segments --     | --     15 -- @ -- -- Note that vertices on higher (closer to the root) segments are assigned smaller indices. This is--- very internally very important when calculating `lca`.+-- internally very important when calculating `lca`. -- -- ===== `headHld`: Vertex -> Vertex --@@ -60,7 +60,7 @@ -- @ -- (-1)==0==8==7==3==1==2==12==13==15     XX: original Vertex --       |        |---    5==8        1==11=8+--    5==8        1==11==8 --       | --       5 -- @@@ -218,7 +218,7 @@ -- -- ==== Constraints -- - \(n \ge 1\)--- - The input graph must be a tree; the edges must be non-directed (both \((u, v, w)\) and+-- - The input graph must be a tree; the edges must be undirected (both \((u, v, w)\) and --   \((v, u, w)\) edges are required). -- -- @since 1.1.0.0@@ -230,7 +230,7 @@ -- -- ==== Constraints -- - \(n \ge 1\)--- - The input graph must be a tree; the edges must be non-directed (both \((u, v, w)\) and+-- - The input graph must be a tree; the edges must be undirected (both \((u, v, w)\) and --   \((v, u, w)\) edges are required). -- -- @since 1.1.0.0@@ -242,9 +242,9 @@         0         (VU.singleton (-1))         (VU.singleton 0)-        (VU.singleton (-1))         (VU.singleton 0)         (VU.singleton 0)+        (VU.singleton 0)         (VU.singleton 1)   | otherwise = runST $ do       -- Re-create adjacent vertices so that the biggest subtree's head vertex comes first.@@ -364,7 +364,7 @@ ancestor :: (HasCallStack) => Hld -> Vertex -> Int -> Vertex ancestor Hld {..} parent k0 = inner parent k0   where-    !_ = ACIA.runtimeAssert (0 <= k0 && k0 <= depthHld VG.! parent) $ "AtCoder.Extra.Tree.Hld.ancestor: k-th ancestor is out of the bounds (`k = " ++ show k0 ++ "`)"+    !_ = ACIA.runtimeAssert (0 <= k0 && k0 <= depthHld VG.! parent) $ "AtCoder.Extra.Tree.Hld.ancestor: k-th ancestor is out of bounds (`k = " ++ show k0 ++ "`)"     inner v k       -- on this segment       | k <= iv - ihv = revIndexHld VG.! (iv - k)
src/AtCoder/Extra/Tree/Lct.hs view
@@ -360,7 +360,7 @@ jump :: (HasCallStack, PrimMonad m, Monoid a, VU.Unbox a) => Lct (PrimState m) a -> Vertex -> Vertex -> Int -> m Vertex jump lct u v k = stToPrim $ jumpST lct u v k --- | \(O(\log n)\) Returns the LCA of \(u\) and \(v\). Because the root of the underlying changes+-- | \(O(\log n)\) Returns the LCA of \(u\) and \(v\). Because the root of the underlying tree changes -- in almost every operation, one might want to use `evert` beforehand. -- -- ==== Constraints@@ -397,10 +397,10 @@     !_ = ACIA.checkIndex "AtCoder.Extra.Lct.prodPath" v (nLct lct)  -- | Amortized \(O(\log n)\). Fold the subtree under \(v\), considering \(p\) as the root-side--- vertex. Or, if \(p\) equals to \(v\), \(v\) will be the new root.+-- vertex. Or, if \(p\) equals \(v\), \(v\) will be the new root. -- -- ==== Constraints--- - The inverse operator has to be set on consturction (`newInv` or `buildInv`).+-- - The inverse operator has to be set on construction (`newInv` or `buildInv`). -- -- @since 1.1.1.0 {-# INLINE prodSubtree #-}
src/AtCoder/Extra/Tree/TreeMonoid.hs view
@@ -17,7 +17,7 @@ -- o--o--o  --> o-x-o-x-o -- @ ----- Idea 2. Assign edge weight to the deeper vertex. The is the internal implementation of+-- Idea 2. Assign edge weight to the deeper vertex. This is the internal implementation of -- `fromEdges` and LCAs are ignored on `prod`: -- -- @@@ -66,7 +66,6 @@ -- >>> let edges = VU.fromList [(0, 1, Sum (1 :: Int)), (1, 2, Sum 2), (2, 3, Sum 3), (1, 4, Sum 4), (4, 5, Sum 5)] -- >>> -- note that the edges must be bi-directed: -- >>> let tree = Gr.build n $ Gr.swapDupe edges--- >>> let hld = Hld.new tree -- >>> let hld = Hld.new tree -- >>> -- note that the edge doesn't have to be bi-directed: -- >>> tm <- TM.fromEdges hld {- `Sum` is commutative -} Commute edges
src/AtCoder/Extra/Vector.hs view
@@ -31,5 +31,5 @@     )     $ VU.generate (VU.length xs) id --- TODO: maybe add lexical permutations, combinations and subsequences.+-- TODO: maybe add lexicographic permutations, combinations, and subsequences. 
src/AtCoder/Extra/WaveletMatrix/BitVector.hs view
@@ -11,7 +11,7 @@     -- * Constructor     build, -    -- * (Internal) Word-based cumultaive sum+    -- * (Internal) Word-based cumulative sum     wordSize,     csumInPlace, 
src/AtCoder/Extra/WaveletMatrix/Raw.hs view
@@ -7,7 +7,7 @@ -- NOTE: We could integrate cumulative sum / fenwick tree / segment tree. -- NOTE: `topK` and `intersects` are not implemented as they are slow. --- | A static Wavelet Matrix without automatic index comperssion. Consider using+-- | A static Wavelet Matrix without automatic index compression. Consider using -- @AtCoder.Extra.WaveletMatrix@ instead. -- -- @since 1.1.0.0
src/AtCoder/Extra/WaveletMatrix2d.hs view
@@ -45,7 +45,7 @@   ( -- * Wavelet matrix 2D     WaveletMatrix2d (..), -    -- * Counstructor+    -- * Constructor     new,     build, 
src/AtCoder/FenwickTree.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE RecordWildCards #-} --- | A Fenwick tree, also known as binary indexed tree. Given an array of length \(n\), it processes+-- | A Fenwick tree, also known as a binary indexed tree. Given an array of length \(n\), it processes -- the following queries in \(O(\log n)\) time. -- -- - Updating an element@@ -270,7 +270,7 @@ -- ==== Constraints -- - if \(f\) is called with the same argument, it returns the same value, i.e., \(f\) has no side effect. -- - \(f(0)\) returns `True`--- - \(0 \leq l \leq n\)+-- - \(0 \leq r \leq n\) -- -- ==== Complexity -- - \(O(\log n)\)@@ -284,7 +284,7 @@   FenwickTree (PrimState m) a ->   -- | \(r\)   Int ->-  -- | \(p\): user prediate+  -- | \(p\): user predicate   (a -> m Bool) ->   -- | \(l\): \(p\) holds for \([l, r)\)   m Int
src/AtCoder/Internal/Assert.hs view
@@ -356,7 +356,7 @@ errorRect funcName x1 x2 y1 y2 w h =   error $ funcName ++ ": given invalid rectangle `[" ++ show x1 ++ ", " ++ show x2 ++ ") x [" ++ show y1 ++ ", " ++ show y2 ++ ")` for rectangle `[0, " ++ show w ++ ") x [0, " ++ show h ++ ")`" --- | \(O(1)\) Asserts \(x_1 \le x_2\) and \(y_1 \le \y_2\).+-- | \(O(1)\) Asserts \(x_1 \le x_2\) and \(y_1 \le y_2\). -- -- @since 1.2.3.0 {-# INLINE checkRectShape #-}
src/AtCoder/Internal/Bit.hs view
@@ -25,9 +25,9 @@   ) where --- TODO: faster implmentation+-- TODO: faster implementation --- | \(O(w)\) Returns minimum \(2^i s.t. 2^i \geq n\).+-- | \(O(w)\) Returns minimum \(2^i\) s.t. \(2^i \geq n\). -- -- @since 1.0.0.0 {-# INLINE bitCeil #-}
src/AtCoder/Internal/Buffer.hs view
@@ -15,12 +15,12 @@ -- -- Append elements with `pushBack`: ----- >>> B.pushBack buf 10 -- [10  _  _ _]+-- >>> B.pushBack buf 10 -- [10  _   _  _] -- >>> B.pushBack buf 11 -- [10, 11  _  _] -- >>> length buf -- 2 ----- Access each elements with `read`, `readMaybe`, `write`, `modify` or `modifyM`:+-- Access each element with `read`, `readMaybe`, `write`, `modify` or `modifyM`: -- -- >>> B.read buf 0 -- 10@@ -36,7 +36,7 @@ -- -- >>> B.write buf 1 0   -- [10, 0,  _  _] ----- Remove elements with `pushBack`:+-- Remove elements with `popBack`: -- -- >>> B.popBack buf     -- [10  _  _  _] -- Just 0
src/AtCoder/Internal/Csr.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE RecordWildCards #-} --- | Immutable Compresed Sparse Row. It is re-exported from the @AtCoder.Extra.Graph@ module with+-- | Immutable Compressed Sparse Row. It is re-exported from the @AtCoder.Extra.Graph@ module with -- additional functionalities. -- -- ==== __Example__
src/AtCoder/Internal/String.hs view
@@ -90,9 +90,9 @@ {-# INLINEABLE saIsImpl #-} saIsImpl ::   (HasCallStack) =>-  -- | naive threshould+  -- | naive threshold   Int ->-  -- | doubling threshould+  -- | doubling threshold   Int ->   -- | string   VU.Vector Int ->
src/AtCoder/LazySegTree.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE RecordWildCards #-} --- | A lazily propagted segment tree. It is the data structure for the pair of a [monoid](https://en.wikipedia.org/wiki/Monoid)+-- | A lazily propagated segment tree. It is the data structure for the pair of a [monoid](https://en.wikipedia.org/wiki/Monoid) -- \((S, \cdot: S \times S \to S, e \in S)\) and a set \(F\) of \(S \to S\) mappings that satisfies -- the following properties. --@@ -15,8 +15,8 @@ -- - Calculating the product of the elements of an interval -- -- In Haskell types, \(F\) is a `SegAct` (@'segAct' f@) and \(S\) is a `Monoid`. For simplicity, in--- this document, we assume that the relevant methods work in constant time. If these they work in--- \(O(T)\) time, each time complexity appear in this document is multipled by \(O(T)\).+-- this document, we assume that the relevant methods work in constant time. If these work in+-- \(O(T)\) time, each time complexity appear in this document is multiplied by \(O(T)\). -- -- ==== __Example__ -- Here we'll use `AtCoder.Extra.Monoid.Affine1` as a monoid action \(F\) and `Data.Semigroup.Sum`
src/AtCoder/MaxFlow.hs view
@@ -264,10 +264,10 @@ edges g = stToPrim $ edgesST g  -- | \(O(1)\) Changes the capacity and the flow amount of the $i$-th edge to @newCap@ and--- @newFlow@, respectively. It oes not change the capacity or the flow amount of other edges.+-- @newFlow@, respectively. It does not change the capacity or the flow amount of other edges. -- -- ==== Constraints--- - \(0 \leq \mathrm{newflow} \leq \mathrm{newcap}\)+-- - \(0 \leq \mathrm{newFlow} \leq \mathrm{newCap}\) -- -- ==== Complexity -- - \(O(1)\)
src/AtCoder/ModInt.hs view
@@ -236,7 +236,7 @@  -- | Retrieve the mod from a `ModInt` object. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.0.0.0@@ -246,7 +246,7 @@  -- | Returns the internal value in `Int`. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.0.0.0@@ -257,7 +257,7 @@ -- | Returns the internal value as `Word32` without type conversion. It is the function for -- constant-factor speedup. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.0.0.0@@ -267,7 +267,7 @@  -- | Returns the internal value in `Word32`. ----- ==== Complecity+-- ==== Complexity -- - \(O(1)\) -- -- @since 1.0.0.0
src/AtCoder/SegTree.hs view
@@ -4,8 +4,8 @@ -- \((S, \cdot: S \times S \to S, e \in S)\), i.e., the algebraic structure that satisfies the -- following properties. ----- - associativity: \((a \cdot b) \cdot c\) = \(a \cdot (b \cdot c)\) for all \(a, b, c \in S\)--- - existence of the identity element: \(a \cdot e\) = \(e \cdot a\) = \(a\) for all \(a \in S\)+-- - associativity: \((a \cdot b) \cdot c = a \cdot (b \cdot c)\) for all \(a, b, c \in S\)+-- - existence of the identity element: \(a \cdot e = e \cdot a = a\) for all \(a \in S\) -- -- Given an array \(S\) of length \(N\), it processes the following queries in \(O(\log N)\) time -- (see [Appendix](./appendix.html) for further details).@@ -14,8 +14,8 @@ -- - Calculating the product of the elements of an interval -- -- For simplicity, in this document, we assume that the oracles @op@ and @e@ work in constant time.--- If these oracles work in \(O(T)\) time, each time complexity appear in this document is--- multipled by \(O(T)\).+-- If these oracles work in \(O(T)\) time, each time complexity appearing in this document is+-- multiplied by \(O(T)\). -- -- ==== __Example__ -- Create a `SegTree` of @'Sum' Int@:
src/AtCoder/String.hs view
@@ -1,6 +1,6 @@ -- | It contains string algorithms. ----- Let \(s\) be a string. We denote the substring of \(s\) between \(a\)-th and \(b - 1\)-th+-- Let \(s\) be a string. We denote the substring of \(s\) between the \(a\)-th and \(b - 1\)-th -- character by \(s[a..b)\). -- -- ==== __Examples__
test/Main.hs view
@@ -13,6 +13,7 @@ import Tests.Extra.DynSparseSegTree.Persistent qualified import Tests.Extra.Graph qualified import Tests.Extra.HashMap qualified+import Tests.Extra.Hld qualified import Tests.Extra.IntMap qualified import Tests.Extra.IntSet qualified import Tests.Extra.IntervalMap qualified@@ -71,6 +72,7 @@             testGroup "DynSparseSegTree.Persistent" Tests.Extra.DynSparseSegTree.Persistent.tests,             testGroup "Graph" Tests.Extra.Graph.tests,             testGroup "HashMap" Tests.Extra.HashMap.tests,+            testGroup "Hld" Tests.Extra.Hld.tests,             testGroup "IntervalMap" Tests.Extra.IntervalMap.tests,             testGroup "Ix0" Tests.Extra.Ix0.tests,             testGroup "IntMap" Tests.Extra.IntMap.tests,
test/Tests/Extra/Graph.hs view
@@ -11,12 +11,7 @@ import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck as QC--genDag :: Int -> QC.Gen (Gr.Csr ())-genDag n = do-  edges <- VU.fromList <$> QC.sublistOf [(u, v) | u <- [0 .. n - 1], v <- [u + 1 .. n - 1]]-  verts <- VU.fromList <$> QC.shuffle [0 .. n - 1]-  pure $ Gr.build n $ VU.map (\(!u, !v) -> (verts VG.! u, verts VG.! v, ())) edges+import Tests.Util (genDag)  reachableFlags :: Int -> (Int -> VU.Vector Int) -> Int -> VU.Vector Bool reachableFlags n gr u0 = VU.create $ do@@ -44,7 +39,7 @@ prop_topSort :: QC.Gen QC.Property prop_topSort = do   n <- QC.chooseInt (1, 3)-  dag <- genDag n+  dag <- genDag @() n   let vs = Gr.topSort n (dag `Gr.adj`)   let perms = map (VU.fromListN n) $ L.permutations [0 .. n - 1]   pure $ vs QC.=== minimum (filter (testTopSort n dag) perms)@@ -89,9 +84,46 @@   let path = Gr.constructPathFromRoot parents 3   path @?= VU.fromList [0, 1, 2, 3] +unit_one :: TestTree+unit_one = testCase "one" $ do+  let !gr = Gr.build @Int 1 VU.empty+  Gr.topSort 1 (Gr.adj gr) @?= VU.singleton 0+  Gr.scc gr @?= V.singleton (VU.singleton 0)+  Gr.rev gr @?= gr+  Gr.findCycleDirected gr @?= Nothing+  Gr.findCycleUndirected gr @?= Nothing+  Gr.connectedComponents 1 (Gr.adj gr) @?= V.singleton (VU.singleton 0)+  (VU.length <$> (Gr.bipartiteVertexColors 1 (Gr.adj gr))) @?= Just 1+  -- Gr.blockCut 1 (Gr.adj gr)+  -- Gr.blockCutComponents 1 (Gr.adj gr)+  Gr.bfs 1 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= (VU.singleton 7)+  Gr.trackingBfs 1 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= (VU.singleton 7, VU.singleton (-1))+  Gr.bfs01 1 0 (Gr.adjW gr) (VU.singleton (0, 7)) @?= (VU.singleton 7)+  Gr.trackingBfs01 1 0 (Gr.adjW gr) (VU.singleton (0, 7)) @?= (VU.singleton 7, VU.singleton (-1))+  Gr.dijkstra 1 0 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= (VU.singleton 7)+  Gr.trackingDijkstra 1 0 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= (VU.singleton 7, VU.singleton (-1))+  Gr.bellmanFord 1 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= Just (VU.singleton 7)+  Gr.trackingBellmanFord 1 (Gr.adjW gr) (-1 :: Int) (VU.singleton (0, 7)) @?= Just (VU.singleton 7, VU.singleton (-1))+  Gr.floydWarshall 1 VU.empty (maxBound `div` 2 :: Int) @?= VU.singleton 0+  Gr.trackingFloydWarshall 1 VU.empty (maxBound `div` 2 :: Int) @?= (VU.singleton 0, VU.singleton (-1))+  (!fw, !prev) <- Gr.newTrackingFloydWarshall 1 VU.empty (maxBound `div` 2 :: Int)+  let test = do+        fw' <- VU.unsafeFreeze fw+        prev' <- VU.unsafeFreeze prev+        (fw', prev') @?= (VU.singleton 0, VU.singleton (-1))+  test+  -- add positive self-loop edge+  Gr.updateEdgeFloydWarshall fw 1 (maxBound `div` 2) 0 0 1+  test+  -- add negative self-loop edge+  Gr.updateEdgeFloydWarshall fw 1 (maxBound `div` 2) 0 0 (-1)+  {- TODO: write test here -}+  pure ()+ tests :: [TestTree] tests =   [ QC.testProperty "topSort" prop_topSort,     -- not writing much tests, as we have verification problems-    QC.testProperty "floydWarshall" prop_floydWarshall+    QC.testProperty "floydWarshall" prop_floydWarshall,+    unit_one   ]
+ test/Tests/Extra/Hld.hs view
@@ -0,0 +1,36 @@+module Tests.Extra.Hld where++import AtCoder.Extra.Graph qualified as Gr+import AtCoder.Extra.Tree.Hld qualified as Hld+import AtCoder.Extra.Tree.TreeMonoid qualified as Tm+import Data.Monoid (Sum (..))+import Data.Vector.Unboxed qualified as VU+import Test.Tasty+import Test.Tasty.HUnit++unit_one :: TestTree+unit_one = testCase "one" $ do+  let hld = Hld.new $ Gr.build @() 1 VU.empty+  (@?= 0) $ Hld.lca hld 0 0+  (@?= 0) $ Hld.ancestor hld 0 0+  (@?= Just 0) $ Hld.jump hld 0 0 0+  (@?= 0) $ Hld.lengthBetween hld 0 0+  (@?= [0]) $ Hld.path hld 0 0+  (@?= [(0, 0)]) $ Hld.pathSegmentsInclusive Hld.WeightsAreOnVertices hld 0 0+  (@?= []) $ Hld.pathSegmentsInclusive Hld.WeightsAreOnEdges hld 0 0+  (@?= (0, 0)) $ Hld.subtreeSegmentInclusive hld 0+  (@?= True) $ Hld.isInSubtree hld 0 0++  tm <- Tm.fromVerts hld Tm.Commute (VU.singleton (Sum (1 :: Int)))+  (@?= Sum 1) =<< Tm.prod tm 0 0+  (@?= Sum 1) =<< Tm.read tm 0+  Tm.write tm 0 $ Sum 2+  (@?= Sum 2) =<< Tm.exchange tm 0 (Sum 3)+  Tm.modify tm (+ (Sum 1)) 0+  (@?= Sum 4) =<< Tm.read tm 0+  (@?= Sum 4) =<< Tm.prod tm 0 0++tests :: [TestTree]+tests =+  [ unit_one+  ]
test/Tests/Extra/WaveletMatrix2d.hs view
@@ -9,14 +9,10 @@ import Data.List qualified as L import Data.Map qualified as M import Data.Maybe (fromMaybe)-import Data.Ord (comparing) import Data.Semigroup (Sum (..))-import Data.Vector.Algorithms.Intro qualified as VAI import Data.Vector.Unboxed qualified as VU-import Test.Hspec import Test.QuickCheck.Monadic as QCM import Test.Tasty-import Test.Tasty.HUnit import Test.Tasty.QuickCheck as QC import Tests.Util (intervalGen) 
test/Tests/SegTree.hs view
@@ -20,7 +20,6 @@ import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.Hspec-import Util (DoNotUnboxLazy (..))  data SegTreeNaive s a = SegTreeNaive   { nStn :: {-# UNPACK #-} !Int,@@ -71,7 +70,7 @@ freezeStn :: (Monoid a, VU.Unbox a, PrimMonad m) => SegTreeNaive (PrimState m) a -> m (VU.Vector a) freezeStn = VU.freeze . dStn -type FooRepr = DoNotUnboxLazy String+type FooRepr = VU.DoNotUnboxStrict String  newtype Foo = Foo String   deriving (Eq, Ord, Show)@@ -90,9 +89,9 @@  instance VU.IsoUnbox Foo FooRepr where   {-# INLINE toURepr #-}-  toURepr (Foo s) = DoNotUnboxLazy s+  toURepr (Foo s) = VU.DoNotUnboxStrict s   {-# INLINE fromURepr #-}-  fromURepr (DoNotUnboxLazy s) = Foo s+  fromURepr (VU.DoNotUnboxStrict s) = Foo s  newtype instance VU.MVector s Foo = MV_Foo (VU.MVector s FooRepr) 
test/Tests/Util.hs view
@@ -1,7 +1,25 @@-module Tests.Util (myForAllShrink, laws, intervalGen, intervalGen') where+module Tests.Util+  ( myForAllShrink,+    laws,+    intervalGen,+    intervalGen',+    Dag (..),+    genDag,+    Tree (..),+    genTree,+  )+where +import AtCoder.Extra.Graph qualified as Gr+import AtCoder.Internal.Assert qualified as ACIA+import Data.Foldable (for_)+import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable, typeRep)+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 import Test.QuickCheck.Classes qualified as QCC import Test.QuickCheck.Property qualified as QC import Test.Tasty@@ -51,3 +69,68 @@   l <- QC.chooseInt (xl, xr)   r <- QC.chooseInt (l, xr)   pure (l, r)++genDag :: forall w. (QC.Arbitrary w, VU.Unbox w) => Int -> QC.Gen (Gr.Csr w)+genDag n = do+  edges <- VU.fromList <$> QC.sublistOf [(u, v) | u <- [0 .. n - 1], v <- [u + 1 .. n - 1]]+  verts <- VU.fromList <$> QC.shuffle [0 .. n - 1]+  ws <- VU.fromList <$> QC.vectorOf n (QC.arbitrary @w)+  let es = VU.zipWith (\(!u, !v) !w -> (verts VG.! u, verts VG.! v, w)) edges ws+  pure $ Gr.build n es++-- | Newtype for generating a random DAG.+newtype Dag w = Dag (Gr.Csr w)++instance (QC.Arbitrary w, VU.Unbox w) => QC.Arbitrary (Dag w) where+  arbitrary = do+    QC.Positive n <- QC.arbitrary+    Dag <$> genDag n++-- TODO: commit the upper code first++-- | Prüfer sequence: https://en.wikipedia.org/wiki/Pr%C3%BCfer_sequence+genTreeEdge :: Int -> QC.Gen (VU.Vector (Int, Int))+genTreeEdge n = case n of+  1 -> pure VU.empty+  2 -> pure $ VU.singleton (0, 1)+  _ -> do+    prufer <- QC.vectorOf (n - 2) (QC.chooseInt (0, n - 1))+    pure $ VU.create $ do+      -- sum(deg) = n + (n - 2) at the beginning+      deg <- VUM.replicate n (1 :: Int)+      for_ prufer $ \v -> do+        VGM.modify deg (+ 1) v++      edges <- VUM.unsafeNew (n - 1)++      -- sum(deg) will be 2(n - 1) - 2(n - 2) = 2+      for_ (zip [0 :: Int ..] prufer) $ \(!i, !u) -> do+        -- NOTE: At the beginning, deg[u] > 1, and deg[i] is never decreaesed until iterated+        !v <- fromJust . VU.findIndex (== 1) <$> VU.unsafeFreeze deg+        -- So we're sure u /= v+        let !_ = ACIA.runtimeAssert (u /= v) "u /= v"+        VGM.write edges i (u, v)+        VGM.modify deg (subtract 1) u+        VGM.modify deg (subtract 1) v++      -- The last two vertices with degree one make up the last edge+      uv <- VU.findIndices (== 1) <$> VU.unsafeFreeze deg+      let !_ = ACIA.runtimeAssert (VU.length uv == 2) "not found uv?"+      VGM.write edges (n - 1) (uv VG.! 0, uv VG.! 1)++      -- done+      pure edges++genTree :: forall w. (QC.Arbitrary w, VU.Unbox w) => Int -> QC.Gen (Gr.Csr w)+genTree n = do+  es <- genTreeEdge n+  ws <- VU.fromList <$> QC.vectorOf (n - 1) (QC.arbitrary @w)+  pure . Gr.build n . Gr.swapDupe $ VU.zipWith (\(!u, !v) !w -> (u, v, w)) es ws++-- | Newtype for generating a random tree.+newtype Tree w = Tree (Gr.Csr w)++instance (QC.Arbitrary w, VU.Unbox w) => QC.Arbitrary (Tree w) where+  arbitrary = do+    QC.Positive n <- QC.arbitrary+    Tree <$> genTree n
− test/Util.hs
@@ -1,97 +0,0 @@-{-# LANGUAGE TypeFamilies #-}---- | For compatibility. FIXME: Remove with latest vector-module Util (DoNotUnboxLazy (..)) where--import Data.Coerce (coerce)-import Data.Vector qualified as V-import Data.Vector.Generic qualified as VG-import Data.Vector.Generic.Mutable qualified as VGM-import Data.Vector.Mutable qualified as VM-import Data.Vector.Unboxed qualified as VU-import Data.Vector.Unboxed.Mutable qualified as VUM---- | Newtype which allows to derive unbox instances for type @a@ which--- is normally a "boxed" type. The newtype does not alter the strictness--- semantics of the underlying type and inherits the laizness of said type.--- For a strict newtype wrapper, see 'DoNotUnboxStrict'.------ 'DoNotUnboxLazy' is intended to be unsed in conjunction with the newtype 'As'--- and the type class 'IsoUnbox'. Here's an example which uses the following--- explicit 'IsoUnbox' instance:--------- >>> :set -XTypeFamilies -XStandaloneDeriving -XDerivingVia--- >>> :set -XMultiParamTypeClasses -XTypeOperators -XFlexibleInstances--- >>> import qualified Data.Vector.Unboxed         as VU--- >>> import qualified Data.Vector.Unboxed.Mutable as VUM--- >>> import qualified Data.Vector.Generic         as VG--- >>> import qualified Data.Vector.Generic.Mutable as VGM--- >>> :{--- >>> data Foo a = Foo Int a--- >>>   deriving (Eq, Ord, Show)--- >>> instance VU.IsoUnbox (Foo a) (Int, VU.DoNotUnboxLazy a) where--- >>>   toURepr (Foo i a) = (i, VU.DoNotUnboxLazy a)--- >>>   fromURepr (i, VU.DoNotUnboxLazy a) = Foo i a--- >>>   {-# INLINE toURepr #-}--- >>>   {-# INLINE fromURepr #-}--- >>> newtype instance VU.MVector s (Foo a) = MV_Foo (VU.MVector s (Int, VU.DoNotUnboxLazy a))--- >>> newtype instance VU.Vector    (Foo a) = V_Foo  (VU.Vector    (Int, VU.DoNotUnboxLazy a))--- >>> deriving via (Foo a `VU.As` (Int, VU.DoNotUnboxLazy a)) instance VGM.MVector VUM.MVector (Foo a)--- >>> deriving via (Foo a `VU.As` (Int, VU.DoNotUnboxLazy a)) instance VG.Vector   VU.Vector   (Foo a)--- >>> instance VU.Unbox (Foo a)--- >>> :}------ >>> VU.fromListN 3 [ Foo 4 "Haskell's", Foo 8 "strong", Foo 16 "types" ]--- [Foo 4 "Haskell's",Foo 8 "strong",Foo 16 "types"]------ @since 0.13.2.0-newtype DoNotUnboxLazy a = DoNotUnboxLazy a--newtype instance VUM.MVector s (DoNotUnboxLazy a) = MV_DoNotUnboxLazy (VM.MVector s a)--newtype instance VU.Vector (DoNotUnboxLazy a) = V_DoNotUnboxLazy (V.Vector a)--instance VGM.MVector VUM.MVector (DoNotUnboxLazy a) where-  {-# INLINE basicLength #-}-  {-# INLINE basicUnsafeSlice #-}-  {-# INLINE basicOverlaps #-}-  {-# INLINE basicUnsafeNew #-}-  {-# INLINE basicInitialize #-}-  {-# INLINE basicUnsafeReplicate #-}-  {-# INLINE basicUnsafeRead #-}-  {-# INLINE basicUnsafeWrite #-}-  {-# INLINE basicClear #-}-  {-# INLINE basicSet #-}-  {-# INLINE basicUnsafeCopy #-}-  {-# INLINE basicUnsafeGrow #-}-  basicLength = coerce $ VGM.basicLength @V.MVector @a-  basicUnsafeSlice = coerce $ VGM.basicUnsafeSlice @V.MVector @a-  basicOverlaps = coerce $ VGM.basicOverlaps @V.MVector @a-  basicUnsafeNew = coerce $ VGM.basicUnsafeNew @V.MVector @a-  basicInitialize = coerce $ VGM.basicInitialize @V.MVector @a-  basicUnsafeReplicate = coerce $ VGM.basicUnsafeReplicate @V.MVector @a-  basicUnsafeRead = coerce $ VGM.basicUnsafeRead @V.MVector @a-  basicUnsafeWrite = coerce $ VGM.basicUnsafeWrite @V.MVector @a-  basicClear = coerce $ VGM.basicClear @V.MVector @a-  basicSet = coerce $ VGM.basicSet @V.MVector @a-  basicUnsafeCopy = coerce $ VGM.basicUnsafeCopy @V.MVector @a-  basicUnsafeMove = coerce $ VGM.basicUnsafeMove @V.MVector @a-  basicUnsafeGrow = coerce $ VGM.basicUnsafeGrow @V.MVector @a--instance VG.Vector VU.Vector (DoNotUnboxLazy a) where-  {-# INLINE basicUnsafeFreeze #-}-  {-# INLINE basicUnsafeThaw #-}-  {-# INLINE basicLength #-}-  {-# INLINE basicUnsafeSlice #-}-  {-# INLINE basicUnsafeIndexM #-}-  {-# INLINE elemseq #-}-  basicUnsafeFreeze = coerce $ VG.basicUnsafeFreeze @V.Vector @a-  basicUnsafeThaw = coerce $ VG.basicUnsafeThaw @V.Vector @a-  basicLength = coerce $ VG.basicLength @V.Vector @a-  basicUnsafeSlice = coerce $ VG.basicUnsafeSlice @V.Vector @a-  basicUnsafeIndexM = coerce $ VG.basicUnsafeIndexM @V.Vector @a-  basicUnsafeCopy = coerce $ VG.basicUnsafeCopy @V.Vector @a-  elemseq _ = seq--instance VU.Unbox (DoNotUnboxLazy a)