求x!在k进制下后缀零的个数(洛谷月赛T1)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求x!在k进制下后缀零的个数(洛谷月赛T1)相关的知识,希望对你有一定的参考价值。
求x!在k进制下后缀和的个数
20分:
求十进制下的x!后缀和的个数
40分:
高精求阶乘,直接模拟过程 (我不管反正我不打,本蒟蒻最讨厌高精了)
60分(不管,反正我是70分QAQ,比赛结束后改了数据就a了...):
利用一个定理(网上有求x!在10进制、2进制下后缀和的个数的题,原理一样)
上代码:
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),所以只要求n!中40的某一质因子出现的次数,最后求出最少出现次数就行。根据质因子分解计算k的质因子p在n中出现的次数:
可分解为n!=n*p^e的形式,e=n/p + n/p^2 + n/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了。
以上是关于求x!在k进制下后缀零的个数(洛谷月赛T1)的主要内容,如果未能解决你的问题,请参考以下文章