0

For CodeChef problem C_HOLIC2, I tried iterating over elements: 5, 10, 15, 20, 25,... and for each number checking the number of trailing zeros using the efficient technique as specified over here, but got TLE.

What is the fastest way to solve this using formula method?

Here is the Problem Link

The Hungry Dictator
  • 3,444
  • 5
  • 37
  • 53
Kartik Shenoy
  • 308
  • 3
  • 14

1 Answers1

0

As we know for counting the number of trailing zeros in factorial of a number, the trick used is:

The number of multiples of 5 that are less than or equal to 500 is 500÷5=100

Then, the number of multiples of 25 is 500÷25=20

Then, the number of multiples of 125 is 500÷125=4

The next power of 5 is 625, which is > than 500.

Therefore, the number of trailing zeros of is 100+20+4=124

For detailed explanation check this page

Thus, this count can be represented as:

a busy cat

Using this trick, given a number N you can determine the no. of trailing zeros count in its factorial. Codechef Problem Link

Now, suppose we are given the no. of trailing zeros, count and we are asked the smallest no. N whose factorial has count trailing zeros Codechef Problem Link

Here the question is how can we split count into this representation? a busy cat

This is a problem because in the following examples, as we can see it becomes difficult.

a busy cat

The count jumps even though the no is increasing by the same amount. As you can see from the following table, count jumps at values whose factorials have integral powers of 5 as factors e.g. 25, 50, ..., 125, ...

+-------+-----+
| count | N   |
+-------+-----+
| 1     | 5   |
+-------+-----+
| 2     | 10  |
+-------+-----+
| 3     | 15  |
+-------+-----+
| 4     | 20  |
+-------+-----+
| 6     | 25  |
+-------+-----+
| 7     | 30  |
+-------+-----+
| 8     | 35  |
+-------+-----+
| 9     | 40  |
+-------+-----+
| 10    | 45  |
+-------+-----+
| 12    | 50  |
+-------+-----+
| ...   | ... |
+-------+-----+
| 28    | 120 |
+-------+-----+
| 31    | 125 |
+-------+-----+
| 32    | 130 |
+-------+-----+
| ...   | ... |
+-------+-----+

You can see this from any brute force program for this task, that these jumps occur frequently i.e. at 6, 12, 18, 24 in case of numbers whose factorials have 25.(Interval = 6=1×5+1)

After N=31 factorials will also have a factor of 125. Thus, these jumps corresponding to 25 will still occur with the same frequency i.e. at 31, 37, 43, ...

Now the next jump corresponding to 125 will be at 31+31 which is at 62. Thus jumps corresponding to 125 will occur at 31, 62, 93, 124.(Interval =31=6×5+1)

Now the jump corresponding to 625 will occur at 31×5+1=155+1=156 Thus you can see there exists a pattern. We need to find the formula for this pattern to proceed.

The series formed is 1, 6, 31, 156, ... which is 1 , 1+5 , 1+5+52 , 1+5+52+53 , ...

Thus, nth term is sum of n terms of G.P. with a = 1, r = 5

a busy cat

Thus, the count can be something like 31+31+6+1+1, etc. We need to find this tn which is less than count but closest to it. i.e.

a busy cat

Say the number is count=35, then using this we identify that tn=31 is closest. For count=63 we again see that using this formula, we get tn=31 to be the closest but note that here, 31 can be subtracted twice from count=63. Now we go on finding this n and keep on subtracting tn from count till count becomes 0.

The algorithm used is:

        count=read_no()

        N=0

        while count!=0:

            n=floor(log(4*count+1,5))

            baseSum=((5**n)-1)/4

            baseOffset=(5**n)*(count/baseSum)  // This is integer division

            count=count%baseSum

            N+=baseOffset

        print(N)

Here, 5**n is 5n

Let's try working this out for an example: Say count = 70, Iteration 1:

a busy cat

Iteration 2:

a busy cat

Iteration 3:

a busy cat

Take another example. Say count=124 which is the one discussed at the beginning of this page: Iteration 1:

a busy cat

PS: All the images are completely owned by me. I had to use images because StackOverflow doesn't allow MathJax to be embedded. #StackOverflowShouldAllowMathJax

Kartik Shenoy
  • 308
  • 3
  • 14