zoukankan      html  css  js  c++  java
  • 求x!在k进制下后缀零的个数(洛谷月赛T1)

    求x!在k进制下后缀和的个数

    20分:
        求十进制下的x!后缀和的个数

    40分:

       高精求阶乘,直接模拟过程 (我不管反正我不打,本蒟蒻最讨厌高精了)

    60分
       
    利用一个定理(网上有求x!在10进制、2进制下后缀和的个数的题,原理一样)

     证明:(转自http://www.cnblogs.com/dolphin0520/

        求n的阶乘某个因子a的个数,如果n比较小,可以直接算出来,但是如果n很大,此时n!超出了数据的表示范围,这种直接求的方法肯定行不通。其实n!可以表示成统一的方式。

        n!=(k^m)*(m!)*a   其中k是该因子,m=n/k,a是不含因子k的数的乘积

        下面推导这个公式

        n!=n*(n-1)*(n-2)*......3*2*1

        =(k*2k*3k.....*mk)*a      a是不含因子k的数的乘积,显然m=n/k;

        =(k^m)*(1*2*3...*m)*a

        =k^m*m!*a

        接下来按照相同的方法可以求出m!中含有因子k的个数。

        因此就可以求除n!中因子k的个数

    上代码:

    1 long long fac(long long x,long long y)   
    2 {   
    3     if (x<y)   
    4         return 0; 
    5     else   
    6         return x/y+fac(x/y,y); 
    7 }   

    比如样例:求10!在40进制下后缀和的个数

    X!转40进制只需不停地除以40,所以后缀零的个数等于x!能整除40 的个数。那么决定x!能整除多少个40的原因在于40的质因子(40=2*2*2*5=2^3+5^1),所以只要求在x!中40的某一质因子出现的次数,最后求出最少出现次数就行。根据质因子分解计算k的质因子p在x!中出现的次数:

    可分解为x!=x*p^e的形式,e=x/p + x/p^2 + x/p^3+ ……,根据这个公式就能写出以下函数

    再上个代码:

     1 #include<iostream>
     2 #include<cstdio>   
     3 #include<cmath>   
     4 #define N 3000001   
     5 using namespace std;
     6 long long a[N],b[N];//a数组存k的质因子,b数组存k的某质因子的个数 
     7 long long sum;   
     8 long long n,k; 
     9 long long ans=0x7fffffffffffffff,temp;    
    10 void fenjie(long long s)  //求质因子及个数 (大概不需要解释了吧。。。) 
    11 {    
    12     long long i,j=0;   
    13     for (i=2;i*i<=s;i++)   
    14         if (s%i==0)   
    15         {   
    16             long long count=0;   
    17             a[j]=i;   
    18             while (s%i==0)   
    19             {   
    20                 count++;   
    21                 s/=i;   
    22             }   
    23             b[j++]=count;   
    24         }   
    25     if (s>1)   
    26     {    
    27         a[j]=s;   
    28         b[j++]=1;   
    29     }   //可能容易遗漏,即k本身是质数 
    30     sum=j;   
    31 }   
    32    
    33 long long fac(long long x,long long y)   
    34 {   
    35     if (x<y)   
    36         return 0;  //判断x是否小于y,若小于,结束统计(否则会一直做下去) 
    37     else   
    38         return x/y+fac(x/y,y); //统计n!中a[i]出现的次数 
    39 }   
    40    
    41 int main()   
    42 {   
    43     while (scanf("%lld%lld",&n,&k)==2)  //多组数据嘿嘿嘿(反正有人因为这个没分) 
    44     {   
    45         fenjie(k);  
    46         for(int i=0;i<sum;i++)  
    47         {  
    48             temp=fac(n,a[i]); 
    49             temp/=b[i];  //注意,k可以分解为多个a[i],所以temp还要再除以a[i]的个数 
    50             ans=ans>temp?temp:ans;   
    51         }  
    52         printf("%lld\n",ans);  
    53     }   
    54     return 0;   
    55 }   

    100分:

    洛谷给出的终极巨无霸正解要用到Pollard rho算法来求k的质因子及其个数(反正我不会,而且代码超级长),我直接用了博客上的模板提交,发现确实不超时了,但莫名奇妙地wa了三个点。。。反正赛后改了数据还是ac了。

     

    转载请注明出处:http://www.cnblogs.com/drurry/
  • 相关阅读:
    使用四元数点乘比较插值是否即将完成
    ShadowGun Demo学习(非技术向)
    测试-关于Unity获取子层级内容的几种接口(Transform FindChild, Component GetComponentInChildren,...)
    Javascript事件模型系列(二)事件的捕获-冒泡机制及事件委托机制
    Javascript事件模型系列(一)事件及事件的三种模型
    在代码中设置IE9的默认文档模式
    如何在博客园的文章/随笔中添加可运行的js代码
    jquery插件:仿百度首页可展开收起的消息提示控件
    有“镜头感”的网页是如何实现的
    HTML5 history API实践
  • 原文地址:https://www.cnblogs.com/drurry/p/7634637.html
Copyright © 2011-2022 走看看