篩選法
求出n以內的素數,最快的應該是篩選法。
篩選法的思路是:
要求10000以內的素數,把1-10000都列出來,1不是素數,划掉;2是素數,所有2的倍數都不是素數,划掉;取出下一個幸存的數,划掉它的所有倍數;直到所有素數找完為止。
這種做法的空間復雜度是O(n),時間復雜度O(n/logn)。
1 const int Max = 1000005; 2 bool prime[Max]={0};//0表示素數,1為非素數 3 4 //篩選n以內的素數 5 void getPrime(int n) 6 { 7 int i,j; 8 int t; 9 for(i = 2; i <= n; i++) 10 { 11 if(!prime[i]) 12 { 13 for(j = 2; (t=j*i) <= n; j++) 14 prime[t] = 1; 15 } 16 } 17 }
分解素因子
唯一質因子分解定理:任意一個合數a僅能以一種方式,寫成如下的乘積形式:
a = p1^e1*p2^e2*...*pr^er
其中pi為素數,p1<p2<...<pr,且ei為正整數。例如數6000=2^4*3*5^3。
素因子的分解技巧:首先a的某兩個素因子不可能同時大於sqrt(a),這樣,先用篩選法求出sqrt(a)以內的所有素數,然后用a依次去mod這些素數,若能整除,則找到素因子,將素因子去掉,再繼續找。最后若a>1,則a也是它的素因子。
1 const int Max = 100005; 2 int isPrime[Max]={0}; 3 int prime[Max/5],num=0; 4 int factors[100],s=0; 5 6 void getPrime(int n) 7 { 8 int i,j; 9 int t; 10 for(i = 2; i <= n; i++) 11 { 12 if(!isPrime[i]) 13 { 14 prime[num++] = i; 15 for(j = 2; (t=i*j) <= n; j++) 16 isPrime[t] = 1; 17 } 18 } 19 } 20 21 void decompose(int n, int* factors) 22 { 23 int te = (int)sqrt(n*1.0); 24 for(int i = 0; i<num&&prime[i]<=te; i++) 25 { 26 if(n%prime[i]==0) 27 { 28 factors[s++] = prime[i]; 29 while(n%prime[i]==0) 30 n = n/prime[i]; 31 } 32 } 33 if(n > 1) 34 factors[s++] = n; 35 }