题目链接:197. 阶乘分解 - AcWing题库
分析:我们知道,n!中含有的质因子一定是小于等于n的,所以我们可以枚举每一个质因子被含有的次数,比如对于一个小于等于n的质因子p,则有1~n中有n/p个数含有p^1,有n/p^2个数含有p^2,但是由于含有p^2的数也含有p^1,而p^1的贡献已经被计算过了,不能重复计算,所以我们单独计算第二个p的贡献即可,所以我们对于每个含有p^2的数的贡献也是1,同理含有p^3,4……的贡献均为1,所以我们就可以o(n)枚举小于等于n的每个质因子然后对于每个质因子再o(logp(n))计算质因子p的贡献,这样总的复杂度就是nlogn
下面是代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
const int N=1e6+10;
int prime[N],cnt;
bool vis[N];
int idx[N];
void init(int n)
{
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]]=true;
if(i%prime[j]==0) break;
}
}
}
int main()
{
int n;
cin>>n;
init(n);
for(int i=1;i<=cnt;i++)
{
int p=prime[i];
for(int j=p;j<=n;j*=p)
{
idx[i]+=n/j;
if(j>n/p) break;
}
}
for(int i=1;i<=cnt;i++)
printf("%d %d\n",prime[i],idx[i]);
return 0;
}
在for循环里面加一个if判断是因为有数据最后一步j=j*p会导致int型数据溢出。可以直接把j开成longlong去掉if判断也可以。