解题思路
正常思路:
枚举1 ~ n,统计每个数的每个质因子的个数,但是时间复杂度为为O(n根号n)。
正确思路:
既然枚举数求质因子不行,那我们就枚举质因子求每个数含有此质因子的个数。
看似好像两个思路就是两层循环在内在外的关系,其实正确思路的时间复杂度为O(nlogn)
n!的每一个质因子都不会超过n,我们可以先筛选出1 ~ n的每个质数p,然后考虑阶乘n!中一共包含多少个质因子。
n!中质因子p的个数就等于1 ~ n每个数包含质因子p的个数之和。在1 ~ n中,p的倍数,即至少包含1个质因子p的显然有floor(n/p)
个。而p^2的倍数,即至少包含2个质因子p的有floor(n/p^2)
个。不过其中的1个质因子已经在floor(n/p)
力统计过,所以只需要再统计第2个质因子,即累加上floor(n/p^2)
,而不是2*floor(n/p^2)
。
不理解可以看这个
AC代码
#include<bits/stdc++.h> #define ll long long using namespace std; const int N=1e6+100; ll prime[N],t,num; bool vis[N]; int n,cnt; void Prime() { for(int i=2;i<=n;i++) { if(!vis[i]) prime[++cnt]=i; for(int j=1;j<=cnt && i*prime[j]<=n;j++) { vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } } int main() { cin>>n; Prime(); for(int i=1;i<=cnt;i++) { num=0;t=prime[i]; while(t<=n) num+=n/t,t*=prime[i]; if(num!=0) cout<<prime[i]<<' '<<num<<endl; } }