标签:include 时间复杂度 数论 复杂度 合数 判断 lse 定义 color
素数,又叫质数,定义是除了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; }
这个程序的时间复杂度是O(n),也是最原始的方法,但是可以优化到o(√n)
快速筛法(埃式筛法):
埃筛--------------埃拉托斯特尼筛法,或者叫埃氏筛法
原理:如果找到一个质数,那么这个质数的倍数都不是质数
比如2是质数,那么4,6,8,10,12...都不是质数
然后看3是质数,那么6,9,12,15,18,21...都不是质数
然后看4,4已经被2标记为合数了,所以跳过
然后看5......这样一直筛下去
时间复杂度是o(n logn logn)
#include<cstdio> 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 = i*i; j < N; j += i){//从i的两倍开始的所有倍数 prime[j] = false; } } } } int main(){ init(); }
好戏都是要留到最后的????确实还有O(n)的做法
这个算法名字叫线筛
这个方法可以保证每个合数都被它最小的质因数筛去
所以一个数只会经过一次
时间复杂度为O(n)
其实loglogn非常小,把埃筛看成线性也无妨,毕竟它比线筛好写
#include<cstdio> 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(); }
基于埃筛的原理,我们可以用它干很多事
比如预处理每个数的所有质因数
#include<cstdio> #include<vector> using namespace std; const int N = 100000 + 5; vector<int > 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<cstdio> #include<vector> using namespace std; const int N = 100000 + 5; vector<int > 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<vector> using namespace std; const int N = 100000 + 5; vector<int > 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(); }
标签:include 时间复杂度 数论 复杂度 合数 判断 lse 定义 color
原文地址:https://www.cnblogs.com/xuyanqd/p/8758908.html