微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

HDU3988(大数分解的应用)

 

HDU3988(大数分解的应用)

分类: 数论   132人阅读  评论(0)  收藏  举报

题目:Harry Potter and the Hide Story@H_502_31@


@H_502_31@

题意:给两个数n和k,找一个最大的i使得k^i能整除n!。这里的n与k都很大,10^18@H_502_31@


@H_502_31@

思路的确还算简单,直接对K素因子分解,然后对于每一个素因子,找出在n!中的个数,然后对应相除,找最小的即可。@H_502_31@


@H_502_31@

只是这里注意一点,就是n!中素因子p的个数一定不会超过LL,这个可以由等比公式求和证明,然后直接素因子分解解决。@H_502_31@


@H_502_31@

@H_502_31@

[cpp]@H_502_31@  view plain copy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <algorithm>  
  5. #include <iostream>  
  6.   
  7. using namespace std;  
  8. typedef unsigned long long LL;  
  9.   
  10. const int Times=10;  
  11. int N=550;  
  12. const LL INF=9223372036854775807ULL;  
  13. LL ct,cnt;  
  14. LL fac[N],num[N];  
  15. LL gcd(LL a,LL b)  
  16. {  
  17.     return b? gcd(b,a%b):a;  
  18. }  
  19. LL multi(LL a,LL b,LL m)  
  20. {  
  21.     LL ans=0;  
  22. while(b)  
  23.     {  
  24.         if(b&1)  
  25.         {  
  26.             ans=(ans+a)%m;  
  27.             b--;  
  28.         }  
  29.         b>>=1;  
  30.         a=(a+a)%m;  
  31.     }  
  32. return ans;  
  33. LL quick_mod(LL a,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">     LL ans=1;  
  34.     a%=m;  
  35.     while(b)  
  36.     {  
  37.         if(b&1)  
  38.         {  
  39.             ans=multi(ans,a,m);  
  40.             b--;  
  41.         }  
  42.         b>>=1;  
  43.         a=multi(a,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important">     }  
  44. return ans;  
  45. }  
  46. bool Miller_rabin(LL n)  
  47. if(n==2) return true;  
  48. if(n<2||!(n&1)) false;  
  49.     LL a,m=n-1,x,y;  
  50.     int k=0;  
  51. while((m&1)==0)  
  52.         k++;  
  53.         m>>=1;  
  54. for(int i=0; i<Times; i++)  
  55.         a=rand()%(n-1)+1;  
  56.         x=quick_mod(a,m,n);  
  57. int j=0; j<k; j++)  
  58.             y=multi(x,n);  
  59.             if(y==1&&x!=1&&x!=n-1) false;  
  60.             x=y;  
  61. if(y!=1) true;  
  62. LL Pollard_rho(LL n,LL c)  
  63.     LL x,y,d,i=1,k=2;  
  64.     y=x=rand()%(n-1)+1;  
  65. while(true)  
  66.         i++;  
  67.         x=(multi(x,n)+c)%n;  
  68.         d=gcd((y-x+n)%n,153); background-color:inherit; font-weight:bold">if(1<d&&d<n) return d;  
  69. if(y==x) return n;  
  70. if(i==k)  
  71.             y=x;  
  72.             k<<=1;  
  73. void find(LL n,int c)  
  74. if(n==1) return;  
  75. if(Miller_rabin(n))  
  76.         fac[ct++]=n;  
  77. return ;  
  78.     LL p=n;  
  79.     LL k=c;  
  80. while(p>=n) p=Pollard_rho(p,c--);  
  81.     find(p,k);  
  82.     find(n/p,k);  
  83. LL getNum(LL p,LL n)  
  84.     LL ans=0;  
  85. while(n)  
  86.         ans+=n/p;  
  87.         n/=p;  
  88. int main()  
  89. int t,tt=1;  
  90.     LL n,kk,minx;  
  91.     scanf("%d",&t);  
  92. while(t--)  
  93.         scanf("%I64u%I64u",&n,&kk);  
  94.         printf("Case %d: ",tt++);  
  95. if(kk==1)  
  96.             puts("inf");  
  97.             continue;  
  98.         ct=0;  
  99.         find(kk,120);  
  100.         sort(fac,fac+ct);  
  101.         num[0]=1;  
  102.         int k=1;  
  103. int i=1; i<ct; i++)  
  104. if(fac[i]==fac[i-1])  
  105.                 ++num[k-1];  
  106. else  
  107.             {  
  108.                 num[k]=1;  
  109.                 fac[k++]=fac[i];  
  110.             }  
  111.         cnt=k;  
  112.         minx=INF;  
  113. int i=0; i<cnt; i++)  
  114.             LL tmp=getNum(fac[i],n)/num[i];  
  115. if(minx>tmp) minx=tmp;  
  116. if(minx==INF)  puts("inf");  
  117. else           cout<<minx<<endl;  
  118. return 0;  
  119. }  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐