• poj1150


    这道题告诉我们递推一定要慢慢细细的推
    Pmn=n!/m!,我们可以先考虑n!的最后一位是什么
    首先最后一位非0位我们首先想到把0都干掉
    也就是先把2和5提出来,这两个其实是同样的方法
    对于N!中有多少个因数2 f(n)=f(n div 2)+ n div 2这个不难想
    提出2和5之后剩下来的数我们只要考虑末位,只可能是1,3,7,9
    当我们讨论末位为x时,设f(n,x)表示N!中提出2和5后某位是x的个数
    首先一个数列实际上可以分成偶数列和奇数列,以1*2*3*4*5*6*7*8*9*10为例
    分成1 3 5 7 9, 2 4 6 8 10
    这样我们尝试分别进行统计,可以发现,实际上2 4 6 8 10中把2提出来就是 1 2 3 4 5 又回到了对n!这种问题
    所以不难得到f(n,x) = f(n/2,x) + g(n,x),g(n)表示奇数列中的数目,所以我们需要解决g(n)
    观察奇数列,实际上又分成了两部分非5的倍数以及5的奇倍数
    根据上面处理的经验不难得到 g(n,x) = n/10+(n%10 >= x)+g(n/5,x)  
    这样对于n!的最末非0位就处理出来了
    而对于n!/m!,我们只要求出m~n之间的2和5的个数,某位为1,3,7,9的个数
    这显然可以用前缀合德思想搞,但要注意2和5的个数谁多谁少

     1 const table:array[1..4,0..3] of longint=((6,2,4,8),
     2                                          (1,3,9,7),
     3                                          (1,7,9,3),
     4                                          (1,9,1,9));
     5 var a:array[0..5] of longint;
     6     f,i,n,m,ans:longint;
     7 
     8 function get2(x:longint):longint;
     9   begin
    10     if x=0 then exit(0)
    11     else exit(x shr 1+get2(x shr 1));
    12   end;
    13 
    14 function get5(x:longint):longint;
    15   begin
    16     if x=0 then exit(0)
    17     else exit(x div 5+get5(x div 5));
    18   end;
    19 
    20 function getx(n,x:longint):longint;
    21   begin
    22     if n=0 then exit(0)
    23     else
    24       if n mod 10>=x then exit(1+n div 10+getx(n div 5,x))
    25       else exit(n div 10+getx(n div 5,x));
    26   end;
    27 
    28 function get(n,x:longint):longint;
    29   begin
    30     if n=0 then exit(0)
    31     else exit(get(n shr 1,x)+getx(n,x));
    32   end;
    33 
    34 begin
    35   while not eof do
    36   begin
    37     readln(n,m);
    38     m:=n-m;
    39     a[1]:=get2(n)-get2(m);
    40     f:=get5(n)-get5(m);
    41     if a[1]<f then
    42     begin
    43       writeln(5);
    44       continue;
    45     end;
    46     ans:=1;
    47     a[2]:=get(n,3)-get(m,3);
    48     a[3]:=get(n,7)-get(m,7);
    49     a[4]:=get(n,9)-get(m,9);
    50     if a[1]<>f then
    51       ans:=ans*table[1,(a[1]-f) mod 4] mod 10;
    52     for i:=2 to 4 do
    53       ans:=ans*table[i,a[i] mod 4] mod 10;
    54     writeln(ans);
    55   end;
    56 end.
    View Code
  • 相关阅读:
    SwiftUI使用URLSession发送https请求免证书验证
    IOS 时间格式 格式化说明
    句柄,文件描述符的理解
    Docker Swarm(8)
    Docker 自己的理解(9)
    eclipse导入idea项目
    写写最近的感悟为什么好久没更
    linux 命令行实现CPU 100%占用
    2.如何正确理解古典概率中的条件概率《zobol的考研概率论教程》
    1.为什么要从古典概率入门概率学《zobol的考研概率论教程》
  • 原文地址:https://www.cnblogs.com/phile/p/4473120.html
Copyright © 2020-2023  润新知