algorithm
complexity
mathematics
programming
optimization

Count sum of multiples of a number below N with O1 complexity?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

If you need the sum of all multiples of m below N, a loop is unnecessary. The values form an arithmetic progression, so the answer can be computed directly with a constant number of arithmetic operations.

Deriving the Constant-Time Formula

The multiples of m below N are:

m, 2m, 3m, ... , km

The last multiplier k is the largest integer such that k * m < N. That means:

k = floor((N - 1) / m)

Once you know k, the sum becomes:

m * (1 + 2 + 3 + ... + k)

The inner sum is the classic triangular-number formula:

1 + 2 + ... + k = k * (k + 1) / 2

So the final result is:

sum = m * k * (k + 1) / 2

That is O(1) because the number of operations does not grow with N.

A Simple Implementation

Here is a direct Python version:

python
1def sum_of_multiples_below(m, n):
2    if m <= 0:
3        raise ValueError("m must be positive")
4    if n <= 0:
5        return 0
6
7    k = (n - 1) // m
8    return m * k * (k + 1) // 2
9
10
11print(sum_of_multiples_below(3, 20))
12print(sum_of_multiples_below(5, 26))

For m = 3 and N = 20, the multiples are 3, 6, 9, 12, 15, 18. Their sum is 63, which matches the formula.

Why This Is Better Than Iteration

A loop-based solution might look like this:

python
1def slow_sum_of_multiples_below(m, n):
2    total = 0
3    for value in range(m, n, m):
4        total += value
5    return total

This version is fine for small inputs, but it performs one addition per multiple. If N is very large, the time cost grows linearly with the number of terms. The formula-based version does the same job instantly.

The constant-time method is especially useful in:

  • math-heavy interview problems
  • Project Euler style exercises
  • performance-sensitive services that repeat the same calculation many times

Once you understand the formula, you can adapt it to nearby problems.

To include N itself when it is a multiple of m, use:

k = floor(N / m)

To count how many multiples exist below N, return k instead of the sum.

To compute the sum of multiples of several divisors, use inclusion-exclusion. For example, the sum of multiples of 3 or 5 below N is:

sum(3) + sum(5) - sum(15)

That subtraction removes numbers counted twice.

Here is a compact JavaScript version for the single-divisor case:

javascript
1function sumOfMultiplesBelow(m, n) {
2  if (m <= 0) {
3    throw new Error("m must be positive");
4  }
5  if (n <= 0) {
6    return 0;
7  }
8
9  const k = Math.floor((n - 1) / m);
10  return (m * k * (k + 1)) / 2;
11}
12
13console.log(sumOfMultiplesBelow(7, 50));

If you use JavaScript Number, remember that very large integers may lose precision. For huge inputs, use BigInt.

Integer Safety and Overflow

The formula is mathematically simple, but the intermediate multiplication can overflow fixed-width integer types. In languages such as C, C++, Java, or C#, promote to a wider type before multiplying.

For example, if m, k, and k + 1 all fit in 32 bits, their product might still exceed the 32-bit range. Python avoids this problem because its integers grow automatically, but many other languages do not.

If overflow is a concern, one trick is to divide one factor by 2 before multiplying when possible:

  • if k is even, compute (k / 2) * (k + 1) * m
  • otherwise compute k * ((k + 1) / 2) * m

That keeps the numbers smaller during intermediate steps.

Common Pitfalls

The most common bug is getting the bound wrong. "Below N" means strict inequality, so a multiple equal to N must be excluded. That is why the correct count uses (N - 1) // m.

Another frequent mistake is forgetting to validate m. If m is zero or negative, the phrase "multiples below N" is either undefined or ambiguous for this problem.

Precision issues are also easy to miss in JavaScript and other languages with floating-point numeric defaults. If the inputs can be large, switch to an integer-safe representation.

Finally, do not confuse O(1) with "always faster in every situation." For tiny inputs, both versions are effectively instant. The value of the formula is correctness, clarity, and predictable scaling.

Summary

  • The multiples of m below N form an arithmetic progression.
  • The count of such multiples is floor((N - 1) / m).
  • The sum is m * k * (k + 1) / 2, which gives a true O(1) solution.
  • Be careful about exclusive versus inclusive bounds.
  • Watch for integer overflow and precision loss in fixed-width or floating-point numeric types.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms