Professional Documents
Culture Documents
Counting Divisors of A Number in (Tutorial) - Codeforces
Counting Divisors of A Number in (Tutorial) - Codeforces
Counting Divisors of A Number in (Tutorial) - Codeforces
Enter | Register
himanshujaju's blog → Pay attention
Before contest
Counting Divisors of a Number in [tutorial] Educational Codeforces Round 19
45:51:12
By himanshujaju, history, 16 months ago, ,
Like 90 people like this. Be the first of your
friends.
Link to PDF (Latex Formatted)
Topic : Counting Divisors of a Number → Top rated
# User Rating
Pre Requisites : Basic Maths , Factorisation , Primality testing
1 tourist 3534
# User Contrib.
The most naive solution here is to do the factorisation. But as we can see, it will
1 Errichto 175
surely receive the Time Limit Exceeded verdict. You may try to compute the prime numbers
till required range and loop over them , but that too exceeds the usual limit of 108 2 rng_58 170
operations. Some optimisations and heuristics may allow you to squeeze through your 3 Petr 161
solution, but usually at the cost of a few TLE's.
4 csacademy 155
→ Find user
Handle:
Looping over all values of P gives us the count of factors of N. Find
Before you move forward to the next section, it would be useful if you try to come up with an
algorithm that finds the count of factors in . As a hint, the way of thinking is same as → Recent actions
http://codeforces.com/blog/entry/22317 1/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
Samsam → Suffix array tutorial
Counting factors in cjquines → Optimization is black magic
moejy0viiiiiv → hihoCoder Challenge 26
Let's start off with some maths to reduce our factorisation to for counting cjquines → Performance of C++11 features
factors :
zoomswk → Codeforces Round #408 (Div.
2) [Editorial]
We write N as product of three numbers P, Q and R.
Hiasat → [Gym] ACM Arabella 2017
geniucos → Invitation to new OI style
contest Info(1) Cup
Errichto → CodeChef April Challenge — a
few days left
riningan → Prime Factorization In log(n)
We will split our number N into two numbers X and Y such that X * Y = N. Further, X After Sieve
contains only prime factors in range and Y deals with higher prime factors ( ).
john_hopes → Numbers less than X of a
Thus, gcd(X , Y) = 1. Let the count of divisors of a number N be denoted by the function range in an array
F(N). It is easy to prove that this function is multiplicative in nature, i.e., Egor → CHelper 3.9
F(m * n) = F(m) * F(n), if gcd(M,N) = 1. So, if we can find F(X) and F(Y), we can also
M_H_M → Just Words
find F(X * Y) or F(N) which is the required quantity.
tube_light → WF Visa Application
For finding F(X), we use the naive trial division to prime factorise X and calculate the PieceOfCake → 'Looking for a challenge'
nice quality.
number of factors. Once this is done, we have Y = N / X remaining to be factorised. This
may look tough, but we can see that there are only three cases which will cover all SuprDewd → Solve problems for a chance
at an interview with Google
possibilities of Y :
Xagak → Google hashcode 2017
1. is a prime number : F(Y) = 2.
pakhandi → Google Code Jam — 2017
2. is square of a prime number : F(Y) = 3.
3. is product of two distinct prime numbers : F(Y) = 4. jonathanirvings → Invitation to TOKI Open
2017
gorbunov → Topcoder Open '17: Marathon
We have only these three cases since there can be at max two prime factors of Y. If it would Matches
have had more than two prime factors, one of them would surely have been , and
rhezo → BAT2 SPOJ
hence it would be included in X and not in Y.
ifsmirnov → Codeforces Round #349
Editorial
So once we are done with finding F(X) and F(Y), we are also done with finding F(X * Y)
or F(N). Detailed →
Pseudo Code :
http://codeforces.com/blog/entry/22317 2/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
N = input()
primes = array containing primes till 10^6
ans = 1
for all p in primes :
if p*p*p > N:
break
count = 1
while N divisible by p:
N = N/p
count = count + 1
ans = ans * count
if N is prime:
ans = ans * 2
else if N is square of a prime:
ans = ans * 3
else if N != 1:
ans = ans * 4
Checking for primality can be done quickly using Miller Rabin. Thus, the time complexity is
for every test case and hence we can solve our problem efficiently.
At this point, you may think that in a similar way, we can reduce this to by handling
some cases. I have not thought much on it, but the number of cases to be handled are high
since after trial division N could be factorised into one, two or three primes. This is easy
enough to code in contest environment, which is our prime objective.
This trick is not quite commonly known and people tend to make bugs in handling the three
cases. A problem in regionals which uses this trick directly :
Problem F | Codeforces Gym
You can try also this technique on problems requiring factorisation for practice
purposes.
Hope you found this useful! Please suggest more problems to be added as well as any
edits, if required.
Happy Coding!
+172 himanshujaju 16 months ago 36
Comments (36) Write comment?
16 months ago, # | 0
Good one :) (Y)
→ Reply
BLANKRK
16 months ago, # | +8
You can't really call this " factorization" though, you only get the
exponents, not the factors.
klamathix
→ Reply
http://codeforces.com/blog/entry/22317 3/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
16 months ago, # ^ | ← Rev. 2 +9
Agreed, that's why I put the title as "Counting Divisors". For the sub
himanshujaju heading, I couldn't think of anything short and simple, so I went ahead
with that. What could it be changed to?
Edit : I edited the post so that it isn't misleading anymore!
→ Reply
16 months ago, # ^ | +3
Looks good now, good work :).
→ Reply
klamathix
No wait I missed some cases, ignore :P
→ Reply
VastoLorde95
16 months ago, # ^ | +3
isnt right, take 101 * 101 * 97 as an example, you just
loop till 40!
himanshujaju → Reply
16 months ago, # ^ | 0
What is N here?
→ Reply
VastoLorde95
16 months ago, # ^ | +3
N = 101 * 101 * 97.
→ Reply
himanshujaju
16 months ago, # ^ | 0
Ah, I see, we don't necessarily have a
prime factor less than the 4th root of the
number
VastoLorde95
→ Reply
16 months ago, # | +5
Auto comment: topic has been updated by himanshujaju (previous revision,
new revision, compare).
himanshujaju → Reply
16 months ago, # | 13
To check if N is prime or not at the end of your algorithm you have to use
O(sqrt(n)) algorithm...
→ Reply
Sa1378
16 months ago, # ^ | +11
Read up on Miller Rabin, I mentioned that explicitly in the post.
→ Reply
himanshujaju
16 months ago, # ^ | 0
Ok...tnx...I'll read about it
→ Reply
http://codeforces.com/blog/entry/22317 4/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
Sa1378
16 months ago, # | 0
You mentioned the following part We have only these three cases since
there can be at max two prime factors of Y. If it would have had
more than two prime factors, one of them would surely have been ,
and hence it would be included in X and not in Y.
kushalsingh007 Could you please explain this part a bit in detail. I am still now sure about why
there can be at max two prime factors for Y and not 3 or more.
→ Reply
16 months ago, # ^ | +3
Suppose N has 3 primes factors left after the trial division is done. So,
N = p1 * p2 * p3.
Now , p1 , p2 and p3 all have to be greater than or else they would
have been found in the trial division. Their product will be greater than
N , which is not possible and hence we contradict what we started
himanshujaju with.
Try a few examples in pen and paper and read this proof again in case
you still don't understand. Don't hesitate to reply for any clarifications.
→ Reply
What is a good way for checking whether a given number is a square?
I'm using this:
bool is_square(ll n) {
ll sqr = sqrt(n);
fofao_funk return sqr * sqr == n;
}
→ Reply
.
→ Reply
bhishma
16 months ago, # ^ | +8
It checks whether n is a power of two, not a square.
→ Reply
Kostroma
16 months ago, # ^ | 8
Sorry guys I accept my mistake, is there a way to remove
the comment
→ Reply
bhishma
16 months ago, # | 0
Someone please provide code for MillerRabin primality test. Thanks!
→ Reply
vikky_codder
4 months ago, # ^ | 0
This provides a nice explanation as well
http://codeforces.com/blog/entry/22317 5/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
This provides a nice explanation as well
→ Reply
mizuki
I tried solving the problem using MillerRabin as you said. The thing is: when we
are limited to ~ 64 bits, doing an exponentiation a^d (mod n) may give overflow.
This happens because, if n is too large (like 10^18), the value of a^d will
overflow before we can apply the modulus operator (applying it when it is less
than n won't help). Is there any way to overcome this or do we need to work with
fofao_funk bigger types?
→ Reply
16 months ago, # ^ | +6
I use this to avoid overflow (taken from topcoder tutorial on primality) :
/* this function calculates (a*b)%c taking into account that
a*b might overflow */
long long mulmod(long long a,long long b,long long c){
long long x = 0,y=a%c;
while(b > 0){
if(b%2 == 1){
x = (x+y)%c;
himanshujaju
}
y = (y*2)%c;
b /= 2;
}
return x%c;
}
→ Reply
16 months ago, # ^ | +10
2015:
#define LL long long
LL mulmod(LL a, LL b, LL c) {
Illidan return (__int128)a * b % c
}
`
→ Reply
16 months ago, # ^ | 0
__int128 is a nonstandart GCC extension. For
example, Microsoft has no plans to implement it in
MSVC
CountZero
→ Reply
16 months ago, # | 0
can u provide links to some spoj problem that uses this technique?
→ Reply
masterwayne
http://codeforces.com/blog/entry/22317 6/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
16 months ago, # ^ | 0
Unfortunately, I know only one question yet. You can use this on any
himanshujaju question where logic for counting factors also passes. Havnt
been solving on SPOJ recently, so no idea.
→ Reply
16 months ago, # | +17
The Pollardrho algorithm can give the factorization of n in O(n1 / 4) time.
→ Reply
NaiveNaive
10 months ago, # | 0
When Y consist of two prime or Y is a prime how can i check it. Thanks in
Advance.
uttom → Reply
10 months ago, # ^ | +4
suppose Y<=10^18.
iterate over all primes from 2 to 10^6 and keep dividing Y by them
meanwhile keep a count of factors.
After this step either you have found the solution or the Y left contains
prime factors > 10^6 .
Arunnsit
NOTE : now notice that Y cant have more than two prime factors
at this step because factors left are already greater than 10^6 .
case 1: Y is prime , using miller rabin test check it .
else case 2 : Y has two prime factors and both of them are >=
10^6 .
→ Reply
10 months ago, # | 0
Am I allowed to translate it to Chinese with your name on it?
→ Reply
RealFan
10 months ago, # ^ | +2
Sure! With/without name doesn't matter much :)
→ Reply
himanshujaju
please can you explain why F(y) ={ 2 , 3 , 4 } in the three cases !! I understand
why we have only three cases but I can't understand who we get F(y) value ..
thanks in advance
→ Reply
MAALA_MH
6 months ago, # ^ | 0
If y is a prime it will have 2 divisors: 1 and y itself. If y is a square of a
prime it will have 3 divisors: 1, sqrt(y) and y itself. If y is a product of
two distinct primes(suppose p1, p2) it will have 4 divisors: 1, p1, p2
and y itself which is equal to p1*p2. I think you forgot to check the link
mentioned in the post about counting divisors using prime
NOxBODY
factorization.
→ Reply
http://codeforces.com/blog/entry/22317 7/8
4/13/2017 Counting Divisors of a Number in [tutorial] Codeforces
4 months ago, # | ← Rev. 2 0
Can someone please let me know how we are maintaining the array of primes for
a very large number like 10^18 for this? Is it possible to return the count for
shallysh93 factors of a dataset extended to 10^18?
→ Reply
3 months ago, # | 0
Can you please share your accepted code for the above Problem.
→ Reply
sam29
Codeforces (c) Copyright 20102017 Mike Mirzayanov
The only programming contests Web 2.0 platform
Server time: Apr/13/2017 19:43:49 (c2).
Desktop version, switch to mobile version.
http://codeforces.com/blog/entry/22317 8/8