Skip to content

Commit c4859f7

Browse files
committed
fix: fixed floor_sum when a < 0 or b < 0.
1 parent cdf0bed commit c4859f7

3 files changed

Lines changed: 21 additions & 17 deletions

File tree

src/alfred/math/flat-geometry.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct Double {
1414
static constexpr int sgn(long double x) {
1515
return (x > eps) - (x < -eps);
1616
}
17-
constexpr long double val(void) const { return val; }
17+
// constexpr long double val(void) const { return val; }
1818
constexpr operator long double(void) const { return val; }
1919
constexpr bool operator==(const Double &rhs) const { return sgn(val - rhs.val) == 0; }
2020
constexpr bool operator!=(const Double &rhs) const { return sgn(val - rhs.val) != 0; }

src/alfred/math/floor-sum.hpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,30 @@
22
#define AFMT_FLOOR_SUM
33

44
// Calculate $\sum_{i = 0}^{n - 1} \lfloor \frac{ai + b}{m} \rfloor$ in $O(\min\{a, m, n\})$
5-
long long floor_sum(
6-
long long a, long long b, long long m, long long n
5+
unsigned long long floor_sum_unsigned(
6+
unsigned long long a, unsigned long long b,
7+
unsigned long long m, unsigned long long n
78
) {
8-
if (a == 0) return b / m * n;
99
if (a >= m || b >= m) {
1010
return (a / m) * (n * (n - 1) / 2) + b / m * n +
11-
floor_sum(a % m, b % m, m, n);
11+
floor_sum_unsigned(a % m, b % m, m, n);
1212
}
13-
long long mx = (a * (n - 1) + b) / m;
14-
return (n - 1) * mx - floor_sum(m, m - b - 1, a, mx);
13+
unsigned long long mx = (a * (n - 1) + b) / m;
14+
return mx ? (n - 1) * mx - floor_sum_unsigned(m, m - b - 1, a, mx) : 0;
15+
}
16+
17+
// Calculate $\sum_{i = 0}^{n - 1} \lfloor \frac{ai + b}{m} \rfloor$ in $O(\min\{a, m, n\})$
18+
long long floor_sum(long long a, long long b, long long m, long long n) {
19+
unsigned long long ans = 0;
20+
if (a < 0) {
21+
unsigned long long a2 = (a % m + m) % m;
22+
ans -= 1ull * n * (n - 1) / 2 * ((a2 - a) / m), a = a2;
23+
}
24+
if (b < 0) {
25+
unsigned long long b2 = (b % m + m) % m;
26+
ans -= 1ull * n * ((b2 - b) / m), b = b2;
27+
}
28+
return ans + floor_sum_unsigned(a, b, m, n);
1529
}
1630

1731
#endif // !AFMT_FLOOR_SUM

src/alfred/math/utils.hpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,6 @@ constexpr bool is_prime(T x) {
1515
return true;
1616
}
1717

18-
template <class T>
19-
inline T gcd(T a, T b) {
20-
return b == 0 ? a : gcd(b, a % b);
21-
}
22-
23-
template <class T>
24-
inline T lcm(T a, T b) {
25-
return a / gcd(a, b) * b;
26-
}
27-
2818
template <class T>
2919
inline T isqrt(T x) {
3020
T res = std::sqrt(x);

0 commit comments

Comments
 (0)