基础知识
1.素数(质数):
素数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。(prime number)
2.性质:
(待填)
3.基本判断思路:
在一般领域,对正整数n,如果用2到 sqrt(n)之间的所有整数去除,均无法整除,则n为质数。
素数筛
1.暴力
按照基本判断思路暴力,可以完成筛选。
时间复杂度O(n*sqrt(n))
bool isprime(int x){ for (int i = 2; i <= x / i; i++){ if(x % i == 0) return false; } if(x < 2)return false; return true; }
2.埃氏筛(一般筛、埃拉托斯特尼筛法)
时间复杂度O(nloglogn)
原理:素数的倍数都为合数
对于从2开始的每一个素数,都要扫一遍倍数,缺点是很多数被重复判断,显然不必要,由此引出欧拉筛法
const int MA = 1e5+5; bool book[MA];//筛 int pri[MA];//存素数 int cnt = -1; void prime(){ memset(book, true, sizeof(book)); book[0] = false , book[1] = false; for(int i=2;i<=MA;i++){ //改进:i*i <= MA if(book[i]){ pri[++cnt] = i; for(int j = i + i ; j <= MA ; j += i){ book[j] = false; } } } }
3.欧拉筛(线性筛)
原理:每一个合数都由它最小的质因数筛去
因为prime[]数组存质数,且是递增
A. i % primes[j] == 0 ,primes[j] 一定是 i的最小质因子,也一定是primes[j]*i的最小质因子
B. i%primes[j] != 0 ,primes[j] 一定 < i的最小质因子 ,因此prime[j]一定是primes[j]*i的最小质因子
结合A,B ,<= j 时,prime[j]一定是primes[j]*i的最小质因子,筛去就好了;
但是对于primes[j+1],prime[j+1]就不是prime[j+1]*i的最小质因数了,因为存在比primes[j+1]更小的质因子,break;
证明:
因为(i%primes[j]==0) 所以 i = k * prime[j];
i * prime[j + 1] = k * prime[j] * prime[j+1]
= k' * prime[j];
prime[j] < prime[j+1]
则 k' > i;
则 对于 i * prime[j+1] 来说,primes[j+1]不是primes[j+1]*i的最小质因数,后面也一样,break;
const int MA = 1e5+5; bool book[MA];//筛 int pri[MA+5];//存素数 int cnt = 0; void prime(){ memset(book,true,sizeof(book)); book[0] = false, book[1] = false; for(int i = 2 ; i <= MA ; i++){ if(book[i]) pri[cnt++] = i; for(int j = 0 ; j < cnt && pri[j] * i <= MA ; j++){ book[pri[j] * i] = false; if(i % pri[j] == 0) //关键 break; } } }