Yes. You can void the for loop altogether and find the sum in constant time.
According to the Inclusion–exclusion principle summing up the multiples of x
and multiples of y
and subtracting the common multiple(s) that got added twice should give us the required sum.
Required Sum = sum of ( multiples of x that are <= N ) +
sum of ( multiples of y that are <= N ) -
sum of ( multiples of (x*y) that are <= N )
Example:
N = 15
x = 3
y = 4
Required sum = ( 3 + 6 + 9 + 12 + 15) + // multiples of 3
( 4 + 8 + 12 ) - // multiples of 4
( 12 ) // multiples of 12
As seen above we had to subtract 12
as it got added twice because it is a common multiple.
How is the entire algorithm O(1)?
Let sum(x, N)
be sum of multiples of x
which are less than or equal to N
.
sum(x,N) = x + 2x + ... + floor(N/x) * x
= x * ( 1 + 2 + ... + floor(N/x) )
= x * ( 1 + 2 + ... + k) // Where k = floor(N/x)
= x * k * (k+1) / 2 // Sum of first k natural num = k*(k+1)/2
Now k = floor(N/x)
can be computed in constant time.
Once k
is known sum(x,N)
can be computed in constant time.
So the required sum can also be computed in constant time.
EDIT:
The above discussion holds true only when x
and y
are co-primes. If not we need to use LCM(x,y)
in place of x*y
. There are many ways to find LCM one of which is to divide product by GCD. Now GCD cannot be computed in constant time but its time complexity can be made significantly lesser than linear time.