题目大意:给出n,m,求P(n,m)最后一位末尾非0数字
解题思路:已知P(n,m)=n!/(n-m)! 由于n,m<=200000000
这里利用到数论中求n!最尾非零数的非零数字的方法(下列数字2,5,1,3,7,9均表示数的个位):
1)因为2,5组成10,故可以删去能配对的2,5,记录下剩余2的个数;(2显然多于5)
2)每一个数,在mod2,5之后只有1,3,7,9四种结果,1可以忽略不计,故我们只需要统计3,7,9的个数
统计方法如下:f(n,x)和g(n,x)中的n代表n!中的n,x取3,7,9中的一个
有:f(n,x)=f(n/2,x)+g(n,x)
g(n,x)=n/10+g(n/5,x)+k
if (n>=x) k=1; else k=0;
这里面是将阶层中的项分为奇数项和偶数项,其中先对奇数项求3,7或9的个数。这里面,很容易知道,每10个数里面一定有一个以3,7或者9结尾的数,而且当n>=3,7或9时,必存在一个3,7,9(当n=16时,前10个数有一个以3结尾,而13也是以上结尾,所以此处有两个3,不是n/10);另外由于要约去成对的2和5那么无可避免的会出现其他的数字(2,3,7,9,1,其中2另外考虑),所以此处要加上g(n/5,x)。对于偶数项,不难发现当偶数项除以2(这里的2由于有另外统计,所以除后对结果没有影响)后就变成了n!的前一半(如10!有1,2,3,4,5,6,7,8,9,10,偶数项除以而后可以转化为1,2,3,4,5。)。
3)最后,找规律,如出现几个2的乘积末尾是多少~~
代码:
1
#include <cstdio>
2
#include <string>
3
#include <iostream>
4
using namespace std;
5
6
int n,m,a,b,c,temp,temp1,d;
7
int p(int n,int x)
8

{
9
if(n<x) return 0;
10
return n/x+p(n/x);
11
}
12
int g(int n,int x)
13

{ if (n<1) return 0;
14
else
15
if (n%10>=x) return n/10+1+g(n/5,x);
16
return n/10+g(n/5,x);
17
}
18
int f(int n,int x)
19

{ if (n<1) return 0;
20
else return f(n/2,x)+g(n,x);
21
}
22
void working()
23

{ int k;
24
a=f(n,3)-f(n-m,3);
25
b=f(n,7)-f(n-m,7);
26
c=f(n,9)-f(n-m,9);
27
temp=p(n,5)-p(n-m,5);
28
temp1=p(n,2)-p(n-m,2);
29
d=temp1-temp;
30
if (a%4==0) a=1; else
31
if (a%4==1) a=3; else
32
if (a%4==2) a=9; else
33
if (a%4==3) a=7;
34
35
if (b%4==0) b=1; else
36
if (b%4==1) b=7; else
37
if (b%4==2) b=9; else
38
if (b%4==3) b=3;
39
40
if (c%4==0) c=1; else
41
if (c%4==1) c=9; else
42
if (c%4==2) c=1; else
43
if (c%4==3) c=9;
44
45
if (d%4==0) d=6; else
46
if (d%4==1) d=2; else
47
if (d%4==2) d=4; else
48
if (d%4==3) d=8;
49
50
printf("%d\n",a*b*c*d%10);
51
52
}
53
int main()
54

{ while (scanf("%d%d",&n,&m)!=EOF)
55
{ working();
56
}
57
58
}
59