Sie sind auf Seite 1von 8

4/13/2017 Counting Divisors of a Number in [tutorial] ­ Codeforces

 
Enter | Register

  HOME CONTESTS GYM PROBLEMSET GROUPS RATING API RCC VK CUP  


     

HIMANSHUJAJU BLOG TEAMS SUBMISSIONS GROUPS CONTESTS

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

Motivation Problem : 2 moejy0viiiiiv 3286


3 ainta 3174
There are T test cases. Each test case contains a number N. For each test case , output 4 ­XraY­ 3170
the number of factors of N.
5 Petr 3135

1 <  = T <  = 10 6 Um_nik 3086


7 LHiC 3060
1 <  = N <  = 1018 8 Merkurev 3055
9 Zlobober 3026
Note : 1 and N are also treated as factors of the number N.
10 RomaWhite 3007

Solution : Countries  | Cities  | Organizations View all →

Naive Solution —   Factorisation   → Top contributors  

# 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

Supposing you fit in the above description and cannot think of anything better than the naive 5 Swistakk 152


solution, I would like to present to you a very simple algorithm which helps you count the 6 Zlobober 149
number of divisors in  , which would be useful for this kind of questions. This 7 GlebsHP 147
algorithm only gives us the count of factors, and not the factors itself.
8 zscoder 143
9 Um_nik 137
Firstly, let's do a quick recap of how we obtain the   algorithm for any number N :
10 Xellos 134
We write N as product of two numbers P and Q. View all →

  → 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

that of getting to the   algorithm.  arman_ferdous → What is the time


complexity?   

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   

We can loop over all prime numbers in range   and try to reduce N to it's prime fcspartakm → Polygon: updates (January —


April 2017)   
factorisation, which would help us count the number of factors of N.
matthew99 → A month before CTSC(Chinese
Team Selection Contest)   
To know how to calculate divisors using prime factorisation, click here.
malcolm → HFT Battle 2017   

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!

  factorisation,  cube root,  large number

      
   +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

16 months ago,  #  | ← Rev. 5       0 

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

16 months ago,  #  | ← Rev. 2       0 

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

16 months ago,  #  ^  | ← Rev. 8       ­20 

.
→ 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 Miller­Rabin 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

16 months ago,  #  | ← Rev. 3       +3 

I tried solving the problem using Miller­Rabin 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 non­standart 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 Pollard­rho 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

6 months ago,  #  | ← Rev. 2       0 

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 2010­2017 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

Das könnte Ihnen auch gefallen