算法:線性篩質數

線性篩質數

功能

輸出從0010000001000000的所有質數。

思路

首先0011不是質數,從22開始逐個判斷是否爲質數。如果tt爲質數,那麼對於任意正整數kkk×tk \times t不是質數,因此可以將k×tk \times t篩去。如果tt已經被篩去,那麼tt不是質數,但仍然要將k×tk \times t篩去。爲了避免重複篩選,需要對篩選條件加以限制,當且僅當kkk×tk \times t除了11以外的最小因數時將k×tk \times t篩去,這樣可以保證每個數最多被篩選11次。當k×tk \times t被篩去時,kk必然爲質數,對於tt,如果tt爲質數,那麼kk22tt;如果tt爲合數,那麼kk22tt除了11以外的最小因數。

時間複雜度

O(n)O(n)

模板

#include <iostream>
using namespace std;
#include <cstring>

const int MAX = 1000000;

int pos;  // the amount of prime
int check[MAX];  // 0 to prime, 1 to composite
int prime[MAX];  // the prime numbers

/**
  * @other: 0 and 1 are not prime numbers
  */
void PRIME() {
  memset(check, 0, sizeof(check));
  pos = 0;
  for (int i = 2; i < MAX; ++i) {
    if (check[i] == 0) prime[pos++] = i;
    for (int j = 0; j < pos; ++j) {
      if (prime[j]*i > MAX) break;  // check the numbers in the range
      check[prime[j]*i] = 1;
      if (i % prime[j] == 0) break;  // to avoid checking repeatly
    }
  }
}

擴展1

利用篩選得到的質數對n進行分解質因數。

模板1.1

#include "PRIME.h"

int count[MAX];  // the amount of prime numbers

/**
  * @param n: number N
  */
void EXT1(int n) {
  memset(count, 0, sizeof(count));
  for (int i = 0; n > 1; ++i) {
    while (n % prime[i] == 0) ++count[i];
  }
}

模板1.2

#include "EXT1.h"

int amount;  // the amount of prime factors
int factor[MAX];  // the prime factors

/**
  * @param n: number N
  */
void EXT2(int n) {
  amount = 0;
  for (int i = 0; prime[i]*prime[i] <= n; ++i) {
    while (n % prime[i] == 0) {
      factor[amount++] = prime[i];
      n /= prime[i];
    }
  }
  if (n > 1) factor[amount++] = n;
}

擴展2

計算n所有因數的和。設一共有kk種質因數,質因數tit_i的數量爲aia_i,那麼因數和爲i=1kj=0aitij\prod^k_{i = 1} \sum^{a_i}_{j = 0} {t_i}^j

模板2

#include "EXT2.h"

/**
  * @param n: number N
  * @return: the sum of factors
  */
int EXT3(int n) {
  int ans = 1;  // the sum of factors
  for (int i = 0; i < pos; ++i) {
    int tmp = 1;  // the power of prime[i]
    int sum = 1;  // the sum of powers
    for (int j = 0; j < count[i]; ++j) {
      tmp *= prime[i];
      sum += tmp;
    }
    ans *= sum;
  }
  return ans;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章