题目大意:
题目链接:http://contest-hunter.org:83/contest/0x30「数学知识」例题/3101 阶乘分解
将
n
!
n!
n!分解质因数。
思路:
n
≤
1
e
6
n\leq 1e6
n≤1e6,肯定是不能直接乘出来再分解的。
那么可以将1到
n
n
n的每个数分解质因数再合起来吗?时间复杂度
O
(
n
n
)
O(n\sqrt{n})
O(nn),依旧不现实。
考虑每一个质数
p
p
p,在1到
n
n
n中,很明显是有
[
p
n
]
[\frac{p}{n}]
[np](
[
]
[]
[]表示向下取整)个数字含有质因数
p
p
p,有
[
p
2
n
]
[\frac{p^2}{n}]
[np2]个数有质因数
p
2
.
.
.
.
.
.
p^2......
p2......有
p
k
n
\frac{p^k}{n}
npk个数含有质因数
p
k
p^k
pk。
所以,
n
!
n!
n!中就有
∑
p
k
≤
n
c
[
p
]
[
k
]
\sum_{p^k\leq n}c[p][k]
∑pk≤nc[p][k]个
p
p
p。
时间复杂度
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
代码:
#include <cstdio>
#define N 2000010
using namespace std;
int p[N],c[N],v[N],n,m;
long long k;
void prime() //线性筛质数
{
for (int i=2;i<=n;i++)
{
if (!v[i])
{
p[++m]=i;
v[i]=i;
}
for (int j=1;j<=m;j++)
{
if (p[j]>v[i]||i*p[j]>n) break;
v[i*p[j]]=p[j];
}
}
}
int main()
{
scanf("%d",&n);
prime();
for (int i=1;i<=m;i++)
{
k=1;
while (k*p[i]<=n)
{
k*=p[i];
c[i]+=n/k; //记录个数
}
}
for (int i=1;i<=m;i++)
printf("%d %d\n",p[i],c[i]);
return 0;
}