1.基础版
bool prime(int x){//判断x是不是质数,是返回true,不是返回false
if(x <= 1) return false;
for(int i = 2; i < x; i ++){
if(x % i == 0) return false;
}
return true;
}
2.进阶版
bool prime(int x){//判断x是不是质数,是返回true,不是返回false
if(x <= 1) return false;
for(int i = 2; i <= sqrt(x + 0.5); i ++){//0.5是防止根号的精度误差
if(x % i == 0) return false;
}
return true;
}
//另一种方法,不需要根号
bool prime(int x){//判断x是不是质数,是返回true,不是返回false
if(x <= 1) return false;
for(int i = 2; i * i <= x; i ++){//用乘法避免根号的精度误差
if(x % i == 0) return false;
}
return true;
}
//根据题目不同,如果i*i会爆int,记得开longlong
例:根据题目不同,有可能你需要先预处理出1~N这N个数是否是素数
如果用刚刚的方法,复杂度就是O(n√n)
#include
const int N = 100000 + 5;
bool prime[N];
bool is_prime(int x){
if(x <= 1) return false;
for(int i = 2; i * i <= x; i ++){
if(x % i == 0) return false;
}
return true;
}
void init(){
for(int i = 0; i < N; i ++){
prime[i] = is_prime(i);
}
}
int main(){
init();
}
3.埃筛---埃拉托斯特尼筛法,或者叫埃氏筛法
原理:如果找到一个质数,那么这个质数的倍数都不是质数
比如2是质数,那么4,6,8,10,12...都不是质数
然后看3是质数,那么6,9,12,15,18,21...都不是质数
然后看4,4已经被2标记为合数了,所以跳过
然后看5......这样一直筛下去
#include
const int N = 100000 + 5;
bool prime[N];
void init(){
for(int i = 2; i < N; i ++) prime[i] = true;//先全部初始化为质数
for(int i = 2; i < N; i ++){
if(prime[i]){//如果i是质数
for(int j = 2*i; j < N; j += i){//从i的两倍开始的所有倍数
prime[j] = false;
}
}
}
}
int main(){
init();
}
埃筛的优化版本
#include
const int N = 100000 + 5;
bool prime[N];
void init(){
for(int i = 2; i < N; i ++) prime[i] = true;
for(int i = 2; i*i < N; i ++){//判断改成i*i
4.线筛
#include
const int N = 100000 + 5;
bool prime[N];//prime[i]表示i是不是质数
int p[N], tot;//p[N]用来存质数
void init(){
for(int i = 2; i < N; i ++) prime[i] = true;//初始化为质数
for(int i = 2; i < N; i++){
if(prime[i]) p[tot ++] = i;//把质数存起来
for(int j = 0; j < tot && i * p[j] < N; j++){
prime[i * p[j]] = false;
if(i % p[j] == 0) break;//保证每个合数被它最小的质因数筛去
}
}
}
int main(){
init();
}
这个方法可以保证每个合数都被它最小的质因数筛去
所以一个数只会经过一次
时间复杂度为O(n)
基于埃筛的原理,我们可以用它干很多事
比如预处理每个数的所有质因数
#include
#include
using namespace std;
const int N = 100000 + 5;
vector prime_factor[N];
void init(){
for(int i = 2; i < N; i ++){
if(prime_factor[i].size() == 0){//如果i是质数
for(int j = i; j < N; j += i){
prime_factor[j].push_back(i);
}
}
}
}
int main(){
init();
}
比如预处理每个数的所有因数
#include
#include
using namespace std;
const int N = 100000 + 5;
vector factor[N];
void init(){
for(int i = 2; i < N; i ++){
for(int j = i; j < N; j += i){
factor[j].push_back(i);
}
}
}
int main(){
init();
}
比如预处理每个数的质因数分解
#include
#include
using namespace std;
const int N = 100000 + 5;
vector prime_factor[N];
void init(){
int temp;
for(int i = 2; i < N; i ++){
if(prime_factor[i].size() == 0){
for(int j = i; j < N; j += i){
temp = j;
while(temp % i == 0){
prime_factor[j].push_back(i);
temp /= i;
}
}
}
}
}
int main(){
init();
}
原博:http://www.cnblogs.com/linyujun/p/5198832.html