1. 程式人生 > >【題解】階乘因子

【題解】階乘因子

pan 自然數 題解 std n) div spl opened 過程

題目描述

桐桐剛剛學習了自然數N的階乘:階乘(N!)被定義成從1到N的所有整數的乘積,例如5!=5×4×3×2×1=120。隨著數N的增大,N!增長的非常快,5!=120,10!=3628800。桐桐想到了一種方法來列舉那麽大的數:不是直接列出該數,而是按照順序列舉出該數中各個質數因子出現的次數。如825可描述為(0 1 2 0 1),意思是對825分解質因數,這些質數因子中有0個2,1個3,2個5,0個7,1個11。請你編一個程序,讀入N值,幫助桐桐按順序輸出N!所包含的質數因子的個數。

輸入輸出格式

輸入格式

一行,一個整數N。(2≤N≤100000)

輸出格式

一行,一個N!中所包含的質數因子的個數(從最小的質數開始)的序列,數與數之間用一個空格隔開。

輸入輸出樣例

輸入樣例

53

輸出樣例

49 23 12 8 4 4 3 2 2 1 1 1 1 1 1 1

題解

表面上看枚舉每一個因子的質因子很麻煩,其實可以順推,枚舉每一個數可以作為哪些數的質因子,在這個過程中順便可以把合數給篩掉。

有一個可以優化的地方:素數除了2以外都為奇數,可以利用這個特性使枚舉時間減半。

技術分享圖片
#include <iostream>
#include 
<cstdio> using namespace std; int n; int a[100001]; int p[100001]; int main() { scanf("%d", &n); int tmp; for(register int i = 4; i <= n; i += 2) { tmp = i; while(!(tmp & 1)) tmp >>= 1, ++a[2]; p[i] = 1; } printf("%d
", a[2] + 1); for(register int i = 3; i <= n; i += 2) { if(p[i]) continue; for(register int j = i + i; j <= n; j += i) { tmp = j; while(!(tmp % i)) tmp /= i, ++a[i]; p[j] = 1; } printf(" %d", a[i] + 1); } return 0; }
參考程序

【題解】階乘因子