@@ -20,26 +20,19 @@ comb2 n = (n `shiftR` 1) * ((n - 1) .|. 1)
20
20
-- floorSum n m a b
21
21
-- Assumptions:
22
22
-- * n: non-negative, m: positive
23
+ -- * a and b can be negative, or >= m
23
24
floorSum :: Int64 -> Int64 -> Int64 -> Int64 -> Int64
24
25
floorSum ! n ! m ! a ! b
25
26
| assert (n >= 0 && m > 0 ) False = undefined
26
- | a < 0 = floorSum n m (- a) (b + a * (n - 1 ))
27
- {-
28
- | m < n = case n `quotRem` m of
29
- (q, n') -> (q * n - comb2 (q + 1) * m) * a +
30
- q * floorSum_positive 0 m m a b +
31
- floorSum_positive 0 n' m a b
32
- -}
27
+ | a < 0 = floorSum_positive 0 n m (- a) (b + a * (n - 1 ))
33
28
| otherwise = floorSum_positive 0 n m a b
34
29
where
35
30
-- Invariants:
36
31
-- * n: non-negative, m: positive, a: non-negative
37
32
-- * 0 <= n <= m
38
33
floorSum_positive :: Int64 -> Int64 -> Int64 -> Int64 -> Int64 -> Int64
39
34
floorSum_positive ! acc ! n ! m ! a ! b
40
- | a == 0 = acc + n * (b `div` m)
41
35
| n == 0 = acc
42
- | m == 1 = acc + a * comb2 n + b * n
43
36
| let m2 = m `quot` 2 , a > m2 =
44
37
let (q, a') = (a + m2) `quotRem` m
45
38
(a'',b'') = if a' < m2 then
0 commit comments