Counting Numbers Divisible by Given Primes | Geeks for Geeks

When I first stumbled upon the problem “Count how many numbers from 1 to M are divisible by any number from a given set of primes”, it looked deceptively simple.
The statement in my head was straightforward:
Input: a set of primes
arr
, and a numberm
.Task: count how many numbers between
1
andm
are divisible by at least one of the primes inarr
.
Let’s solve the given problem…
First Attempt - Brute Force Check
Like any beginner would, I started with the most natural idea:
For each number i
from 1 to m
, check if it is divisible by any prime in the list.
If divisible → increase count and break (no need to check further primes for that i
).
Here’s the code I wrote:
class Solution:
def countDivisible(self, arr, m):
count = 0
for i in range(1, m+1):
for p in arr:
if i % p == 0:
count += 1
break
return count
This worked well for smaller test cases.
But when m
was very large (say 10^7 or more), this solution got TLE.
In fact, it solved 1010/1120 test cases before failing.
And that’s when I realized brute force would never scale here.
Second Attempt - Marking Multiples
Next, I thought: “Why check every number individually? Why not directly mark multiples of primes?”
So I created a Boolean array divisible[]
of size m+1
, initialized to False
.
For each prime
p
, I marked all its multiples asTrue
.Finally, I summed up the Boolean array to count how many were divisible.
Here’s the code I wrote:
class Solution:
def countDivisible(self, arr, m):
divisible = [False] * (m+1)
for p in arr:
for multiple in range(p, m+1, p):
divisible[multiple] = True
return sum(divisible[1:])
This was significantly faster!
Instead of checking each number with every prime, I just walked through multiples.
Complexity dropped to about
O(m/p1 + m/p2 + …)
which is much better thanO(m * len(arr))
.
But still, it failed on very large values of m
.
I got 1110/1120 test cases correct.
Third Attempt - Inclusion-Exclusion Principle
At this point, brute force ideas were exhausted. So I looked deeper into mathematics.
The real trick here is the Inclusion-Exclusion Principle (IEP).
Instead of simulating the divisibility, we can mathematically count directly:
For each subset of primes, calculate the LCM of that subset.
Count how many numbers up to
m
are divisible by that LCM (m // lcm
).If the subset size is odd → add this count.
If even → subtract this count.
This ensures we don’t double-count numbers that are divisible by multiple primes.
Code for Inclusion-Exclusion: With the help of GPT
from math import gcd
class Solution:
def countDivisible(self, arr, m):
n = len(arr)
def lcm(a, b):
return a * b // gcd(a, b)
count = 0
# Iterate through all subsets
for mask in range(1, 1 << n):
subset_lcm = 1
bits = 0
for i in range(n):
if mask & (1 << i):
bits += 1
subset_lcm = lcm(subset_lcm, arr[i])
if subset_lcm > m: # Too large, no contribution
break
else:
contrib = m // subset_lcm
if bits % 2 == 1: # odd subset → add
count += contrib
else: # even subset → subtract
count -= contrib
return count
This method passed all test cases (1120/1120).
It is mathematically elegant and extremely efficient compared to brute force.
Complexity Analysis
Approach 1 (Brute Force):
Time:
O(m * n)
Space:
O(1)
Failed for large
m
.
Approach 2 (Marking Multiples):
Time:
O(m/p1 + m/p2 + …)
≈O(m log m)
in worst case.Space:
O(m)
Faster, but memory heavy for very large
m
.
Approach 3 (Inclusion-Exclusion):
Time:
O(2^n * n * log m)
(since we calculate LCMs for all subsets).Space:
O(1)
Works best when
n
(number of primes) is small (≤ 15).Scales beautifully for large
m
(like 10^12).
Final Thoughts
This problem was a beautiful journey for me:
I started with brute force (got partial AC).
Then I tried a sieve-like marking approach (almost solved).
Finally, with the help of AI and a bit of math, I discovered the Inclusion-Exclusion Principle which cracked the problem fully.
Lesson Learned: Sometimes brute force intuition takes you part of the way, but true optimization comes from stepping back and looking at the mathematical structure of the problem.
Subscribe to my newsletter
Read articles from Prashant Gupta directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
