不會用高精作的蒟蒻獻上本身的第一篇題解(第一次寫,寫的很差你們多多包涵)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; }
終於寫完了人生第一篇題解了,謝謝你們觀看!
完結撒花(。・∀・)ノ🌹