1. 程式人生 > 其它 >階乘分解

階乘分解

階乘 N! 分解質因數

題目連結

acwing197. 階乘分解

題目描述

給定整數 \(N\),試把階乘 \(N!\) 分解質因數,按照算術基本定理的形式輸出分解結果中的 \(p_i\)\(c_i\) 即可。

輸入格式

一個整數 \(N\)

輸出格式

\(N!\) 分解質因數後的結果,共若干行,每行一對 \(p_i,c_i\),表示含有 \({p_i}^{c_i}\) 項。按照 \(p_i\) 從小到大的順序輸出。

資料範圍

\(1≤N≤10^6\)

輸入樣例:

5

輸出樣例:

2 3
3 1
5 1

樣例解釋

\(5!=120=23∗3∗5\)

解題思路

\(n!\) 中質因數 \(p\) 的個數至少有 \(\frac{n}{p}\)

個,\(p^2\) 的個數至少有 \(\frac{n}{p^2}\)個,\(\dots\)
其中,\(p^2\) 中質因子的個數在 \(p\) 中也算過一次,累加即可~
\(n!\) 中質因子的個數:

\[\frac{n}{p}+\frac{n}{p^2}+\dots+\frac{n}{p^{log_pn}} \]
  • 時間複雜度:\(O(nlogn)\)

程式碼

#include<cstdio>
using namespace std;
int prime[1000000];
int v[1000005];
int m,n;
void primes(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!v[i])
        {
            v[i]=i;
            prime[++m]=i;
        }
        for(int j=1;j<=m;j++)
        {
            if(v[i]<prime[j]||i*prime[j]>n)break;
            v[i*prime[j]]=prime[j];
        }
    }
}
int main()
{
    scanf("%d",&n);
    primes(n);
    for(int i=1;i<=m;i++)
    {
        int p=prime[i],c=0,t=n;
        while(t>=p)c+=t/p,t/=p;
        printf("%d %d\n",p,c);
    }
    return 0;
}