数据范围:
3
≤
N
≤
1
0
6
3 \le N \le 10^6
3≤N≤106
首先暴力方法,把N的阶乘算出来再进行分解质因数,此方法时间复杂度太过于庞大且超过long long需要使用高精度,非常麻烦。
N
!
=
1
∗
2
∗
3
∗
.
.
.
.
∗
N
N ! = 1 * 2 * 3 * .... * N
N!=1∗2∗3∗....∗N,我们将其分解质因数得
N
!
=
p
1
a
1
∗
p
2
a
2
∗
p
3
a
3
∗
.
.
.
∗
p
k
a
k
N! = p_1^{a_1} * p_2^{a_2} * p_3^{a_3} * ... * p_k^{a_k}
N!=p1a1∗p2a2∗p3a3∗...∗pkak。我们可以将1,2,3,…,n分别分解质因数即可得到答案。但是时间复杂度也很大,每一次分解质因数都是
O
(
N
)
O(\sqrt N)
O(N)的复杂度。所以我们考虑把每一个数分解,不如反方向考虑,考虑每一个数的倍数。因此我们只需要预处理出
1
0
6
10^6
106以内的质数,然后枚举每一个质数,求一下1~N中
p
i
p_i
pi的有多少个,
p
i
2
p_i^2
pi2有多少个,
.
.
.
p
k
k
...p_k^k
...pkk有多少个。
#include
#include
#include
using namespace std;
const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N];
void init(int n)
{
for(int i = 2; i <= n; i ++)
{
if(!st[i]) primes[cnt ++] = i;
for(int j = 0; primes[j] <= n / i; j ++)
{
st[i * primes[j]] = true;
if(i % primes[j] == 0) break;
}
}
}
int main()
{
int n;
cin >> n;
init(n);
for(int i = 0; i < cnt; i ++)
{
int p = primes[i];
int s = 0;//当前质数的次数
for(int j = n; j; j /= p) s += j / p;
cout << p << " " << s << endl;
}
return 0;
}