1. 程式人生 > 實用技巧 >【題解】p2388階乘之乘

【題解】p2388階乘之乘

原題傳送門

題解一堆\(O(n)\)演演算法真給我看傻了。

考慮\(10=2*5\),因子2肯定更多,所以計算因子5的個數即可。


從5到n這\(n-5+1\)個數的階乘裡面,都各自含有一個因子\(5=1*5\)。

從10到n這\(n-10+1\)個數的階乘裡面,都各自含有一個因子\(10=2*5\)。

故因子5的總個數為\((n-5+1)+(n-10+1)+...+(n \% 5+1)\)。

不難發現這是一個等差數列,首尾項如上,項數為\(n/5\)。


然而這樣並不對,因為我們只考慮到了含有一個因子5的情況,但像\(25=5*5\)這樣含有兩個因子5的情況,我們還得重複計算。

因此,列舉我們要統計的因子i

,並用上面等差數列的思想分別計算其個數,統計入答案即可。


值得注意的一點:由於前面在因子\(i=5\)的時候,我們已經將\(25=5*5\)中的一個因子5統計入答案。

因此當因子\(i=25\)的時候,只要統計剩餘的一個因子5即可。

#include<cstdio>

#define ll long long

using namespace std;

int main()
{
// freopen("in.in","r",stdin);
int n;
scanf("%d",&n);
ll ans=0;
for(int i=5;i<=n;i*=5)
ans+=(ll)((n-i+1)+(n%i+1))*(n/i)/2;
printf("%lld\n",ans);
return 0;
}