From: http://www.cppblog.com/abilitytao/archive/2009/10/31/99907.html
How can I solve this problem? Don't worry. Let's discuss the following sub-problems:
1. How can we find the number of occurrences of X (for example, 5) in the N factorial?
For example, 15 factorial: 1*2*3*4*5*6*7*8*9*10*11*12*13*14*15
Since the prime factor 5 only appears in the multiples of 5, I have extracted 5 from 5, 10, and 15, which is equivalent to 15/5 Prime Factor 5, followed by 5, 10, 15 is changed to 1, 2, 3;
Since the multiples of not 5 are clearly out of consideration, we only need to continue to discuss its subproblem 3! You can.
In this way, we can use recursion to solve this problem. With this method, can we solve n easily! How many zeros are there at the end? Think about it... n! Is the number of the last 0 related to the number of a prime factor? Pai_^
For example, if we want to set the number of occurrences to 5, we can write as follows:
Int get5 (int n) // calculate n! Occurrence times of Medium Factor 5
{
If (n = 0)
Return 0;
Return N/5 + get5 (N/5 );
}
2. How to obtain n! What is the last non-zero factorial?
For example, we are looking for 10! The last digit is not 0, because the combination of prime factor 2 and five will generate 0 at the end. So we may wish to put 10! The prime factor in the middle is removed (but note that the number of 2 is actually more than that of 5, so we need to consider the effect of the additional 2 on the last position at the end)
For example, 1*2*3*4*5*6*7*8*9*10, remove 2, after the 5 factor is 1*1*3*1*1*3*7*1*9*1. Because the 2 or 5 factor has been removed, the end of the remaining number must be 3, 7, 9, one of the four in 1. Then we can find out the number at the end of such a string after multiplication. Then we can add 2 to the effect on the last bit!
To sum up, please 10! The last step is not 0:
Step 1: first set 10! Remove all 2, 5 factors from;
Step 2: Find the number at the end of the multiplication of the remaining number.
Step 3: Because the removed 2 is more than 5, we have to consider the influence of the excess 2 on the result.
Step 4: output your answer!
As mentioned in the above article, "to compute the number of 3, 7, 9 (F(1) mod 10 ),(F(2) mod 10 ),...,(F(N) mod 10) is not so easy ", where Step 2 is difficult. How can we find out the last digit after multiplying the remaining number? This can be converted to the number of occurrences of the numbers ending with 3, 7, and 9 (why? Because the N power of these numbers is regular, and the cycle is 4. If you don't believe it, you can push it)
Well, now the question is how to find the numbers at the end of the string, the number of times they appear;
A series can actually be divided into even columns and odd columns. Take 1*2*3*4*5*6*7*8*9*10 as an example.
Divided into 1 3 5 7 9, 2 4 6 8 10
In this way, we try to make statistics separately. We can find that in fact, the number in 2, 4, 6, 8, 10 is the number in 1, 2, 3, 4, 5, that is to say, we divide this problem into a subproblem of the original problem.
F (n) = f (n/2) + g (N), g (n) represents the number of odd columns, so we need to solve g (N)
Observe g (n) again)
In fact, it is divided into two parts: 1 3 7 9 11 13 17 19 21... And 5 odd multiples of 5, 15, 25... It indicates that a subproblem occurs again. If you want to count the number of X (,) at the end of this series, you can write it as follows: G (n, x) = N/10 + (n % 10> = x) + g (N/5, X)
By using two recursive equations, we can calculate the number of numbers at the end of 1, 3, 7, and 9 in lgn time.
Now we get the number of numbers at the end of the number, which is 3, 7, and 9. We can use the nature of the loop section to quickly calculate the result of MOD 10 after the number is multiplied, after considering the Division 2 at that time (in fact, we can also use the loop section to process it), we can find the answer!
After solving the above two subproblems, it is very easy to calculate the last non-0 bit of P (n, m.
P (n, m) is actually equal to n! /(N-m )!
We can find n! And (n-m )! The number of occurrences of the medium prime factor, and 9, respectively, and then subtract each other.
And then use the loop section to process it!
BTW, pay attention to a trick, that is, if the number of occurrences of 2 is smaller than 5 (this is possible for the number of permutation), we can directly output 5, if the number of 2 is equal to 5, so the cycle section of 2 does not need to be considered. As for the cyclic section 3, 7, and 9, since the last digit of these numbers is exactly 1, you do not need to consider it.
# Include <cstdio> int get2 (int n) {If (n = 0) return 0; return n/2 + get2 (n/2 );} int get5 (int n) {If (n = 0) return 0; return N/5 + get5 (N/5);} int g (int n, int X) {If (n = 0) return 0; return N/10 + (n % 10> = x) + g (N/5, x );} int getx (int n, int X) {If (n = 0) return 0; return getx (n/2, x) + g (n, x );} int table [4] [4] = {6, 2, 4, 8, // The cyclic section of 2. 2 ^ 0 = 1. Special processing is required. 1, 3, 9, 7, // 3, 9, 3, // 7, // 9}; int main () {int n, m; while (scanf ("% d", & N, & M )! = EOF) {int num2 = get2 (N)-get2 (n-m); int num5 = get5 (N)-get5 (n-M ); int num3 = getx (n, 3)-getx (n-M, 3); int num7 = getx (n, 7)-getx (n-M, 7 ); int num9 = getx (n, 9)-getx (n-M, 9); int res = 1; if (num5> num2) {printf ("5 \ n "); continue;} else {If (num5! = Num2) {res * = table [0] [(num2-num5) % 4]; Res % = 10;} res * = table [1] [num3% 4]; res % = 10; Res * = table [2] [num7% 4]; Res % = 10; Res * = table [3] [num9% 4]; res % = 10;} printf ("% d \ n", Res);} return 0 ;}