不会用高精作的蒟蒻献上本身的第一篇题解(第一次写,写的很差你们多多包涵)ios
根本就不用高精的啊喂!优化
数学解法spa
https://www.luogu.com.cn/problem/P2388code
正题开始blog
要求n个阶乘的积,就要先将其中一个数阶乘的乘积求出来。ci
那么一个数阶乘乘积后0的个数要怎么求呢?get
有话快说数学
直接求这个阶乘里有多少个质因数5就行!it
???io
众所周知正整数相乘末尾是0的只能是2的倍数与5的倍数相乘,2的倍数铁定是比5的倍数要多的那么咱们就能够一项一项求了!
暴力代码以下:
#include<iostream> using namespace std; int hhh(long long a) { int sum=0; while(a%5==0)//不能用if,由于要求这里面有多少个质因数5,有的数不止一个,好比25 sum++,a/=5; return sum; } int main() { long long i,n,ans=0,j;//不开long long见祖宗 cin>>n; for(i=1;i<=n;i++) for(j=1;j<=i;j++) ans+=hhh(j);//计算当前数有几个质因数5 cout<<ans; return 0; }
一看就会TLE啊
怎么优化呢?
不要急,且听我慢慢道来
有话快说!
先将1~n的阶乘拆成两部分:
1!=1 2!=2*1! 3!=3*2!……n!=n*(n-1)!
第二部分是咱们上一步算的,因此要求n!后有几个0,只用求n*2^y后0的个数(其实就是求n有几个质因数5)+上一步计算的(n-1)!后0的个数(就是求一、二、3……n-1里有几个质因数5)
改良后的代码以下:
#include<iostream> using namespace std; long long sum=0;//不开long long……我是否是已经说过了? void hhh(long long a) {//不要初始化,要记忆化(迫真 while(a%5==0) sum++,a/=5; } int main() { long long i,n,ans=0; cin>>n; for(i=1;i<=n;i++) hhh(i),ans+=sum; cout<<ans; return 0; }
终于写完了人生第一篇题解了,谢谢你们观看!
完结撒花(。・∀・)ノ🌹