引入问题:
给定整数
N
N
N,试把阶乘
N
!
N!
N! 分解质因数,按照算术基本定理的形式输出分解结果中的
p
i
p_i
pi 和
c
i
c_i
ci即可。
N
!
N!
N!分解质因数后的结果,共若干行,每行一对
p
i
p_i
pi,
c
i
c_i
ci,表示含有
p
i
c
i
p_i^{ci}
pici项。按照
p
i
p_i
pi从小到大的顺序输出。
N
∈
[
1
,
1
e
6
]
N\in[1,1e6]
N∈[1,1e6]
解题思路:
错误:
1)很明显乘出来再分解是很不现实的。
2)如果一个从
[
1
,
n
]
[1,n]
[1,n]去枚举一个个去分解最坏下数量级
n
n
≈
1
e
9
[
n
=
1
e
6
]
n\sqrt n\approx1e9[n=1e6]
nn≈1e9[n=1e6]妥妥超时
正解:
1)我们可以枚举质因子
p
p
p看
[
1
,
n
]
[1,n]
[1,n]里面有多少个是p的倍数
⌊
n
p
⌋
\lfloor {n\over p}\rfloor
⌊pn⌋
2)假如说有多个
p
p
p呢?那么我们就继续看看有多少个数是
p
2
p^2
p2的倍数
⌊
n
p
2
⌋
\lfloor {n\over p^2}\rfloor
⌊p2n⌋
3)同理一直直到某个
x
x
x使得
p
x
>
n
p^x>n
px>n
4)那么
c
=
⌊
n
p
⌋
+
⌊
n
p
2
⌋
+
.
.
.
.
+
⌊
n
p
x
⌋
c= \lfloor {n\over p}\rfloor + \lfloor {n\over p^2}\rfloor + ....+\lfloor {n\over p^x}\rfloor
c=⌊pn⌋+⌊p2n⌋+....+⌊pxn⌋
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
bool vis[N];
int prime[N], cnt;
int n;
void init(int n)
{
for(int i = 2; i <= n; ++ i)
{
if(!vis[i]) prime[cnt ++] = i;
for(int j = 0; j < cnt && i * prime[j] <= n; ++ j)
{
vis[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
}
int main()
{
init(N);
cin >> n;
for(int i = 0; i < cnt; ++ i)
{
int p = prime[i];
int s = 0;
for(int j = n; j; j /= p) s += j / p;
if(s) cout << p << " " << s << endl;
}
return 0;
}