线性筛选素数。。。。线性哦
来源:互联网 发布:php正则去掉html标签 编辑:程序博客网 时间:2024/06/08 06:10
上一篇一道题目用到了筛选素数,不过是那个只需要求3400以内的,比较少,无所谓,关键是如果要求1000000以内的,再直接求就不行了,太慢了。
下面给出两个自己用的模版,并解释解释,为何这样能够很快计算出素数。
代码1,这个有点长,但是很好理解
#include <stdlib.h>#include <stdio.h>#include <string.h>int prime[100000];bool s[1000010];void Prime()//求素数{ int i,j,k,t; for (i=2;i<=1000000;i+=2) s[i]=0; for (i=1;i<=1000000;i+=2) s[i]=1; s[1]=0; s[2]=1; for (i=3;i<=1010;i+=2)//如果要求10000以内的素数,你至少要看i%sqrt(10000)都不可约才行,这也是为什么1000000以内只要i<=1000就行了的道理 { if (s[i]) { k=2*i;//应为所有偶数已经剔除,所以此处t=3*i(相当于)也就是此次剔除的仍是奇数,所以避免了重复剔除偶数,速度快。 t=i+k; while (t<=1000000) { s[t]=0; t=t+k; } } } k=1; prime[1]=2; for (i=3;i<=1000000;i+=2) { if (s[i]==1) { k++; prime[k]=i; } } prime[0]=k; }
上面这个实际上就是先踢出了所有偶数,然后呢,以后要踢出的只能是奇数,否则你就重复预算了。k=2*i 是个偶数,i是奇数,3*i也是奇数,那么每次t=i + k都是奇数。所以每次去除的都是奇数倍了。
这样处理后基本上每个数只判断一次就知道是不是素数了,所以是线性。。。
代码2:难理解一点
const int M = 3000500;int p[400010], pNum;bool f[M];void Prime(){int i, j;for(i = 2; i < M; i++) {if(!f[i]) { p[pNum++] = i; }for(j = 0; j < pNum && p[j] * i < M; j++ ) {f[p[j]*i] = 1;if(!(i%p[j]))break;}}}
这个其实和上面那个是同一个道理。首先f[i]==0就是素数,从2开始。然后我们要去除已经取得素数的i倍的数,f[p[j]*i] = 1;
关键就是下面那句话不好理解,因为正是那句跳出循环才能保证筛选素数是线性的。
为什么i能除尽p[j]这个素数就跳出呢?
其实可以简单证明一下:
合数可以由一个质数数与另一个数相乘得到
而同时假设合数a=质数b×质数c×一个数d
令e=c × d,假设b ≥ c,e为合数,令f=d × b
a=f × c ,其中c
即大的质数和该合数的乘积可用一个更大的合数和比其小的质数相乘得到
这也是if(!( i % prime[j]))break;的含义,这也是线性筛法算质数表的关键所在
举个例子:
比如i = 9,现在素数是2 3 5 7
进入第二重循环了,f[2 * 9] = 1;f[3 * 9] = 1;
这个时候9%3==0,要跳出了,为什么不做f[5* 9] =1;呢?
因为5 * 9 可以用3 * 15来代替,如果这个时候你计算了,那么到i=15的时候这个数还会被重复计算一次,所以这里大量避免了重复运算,所以也就节省了时间。
这里总结一句话就是,一个大的合数和这个能除尽的质数的乘积,一定能被一个比起小的质数和合数更大的合数乘积来代替。
不懂的时候想想 5*9 = 5*3*3 = 3*15就是这个道理。
- 线性筛选素数。。。。线性哦
- 线性筛选素数模板
- 素数线性筛选
- 素数的线性筛选
- 线性筛选素数法
- 线性筛选素数
- 素数线性筛选法
- 素数线性筛选
- 线性筛选求素数
- 线性筛选求素数
- 【线筛】线性筛选素数
- 线性筛选素数--python
- 浅谈—线性筛选素数
- 快速线性素数筛选[模板]
- 线性筛选素数(模板)
- 线性筛选素数(欧拉筛选)
- 线性筛选素数和线性筛选欧拉函数【bzoj2190]
- 素数筛选之“普通筛选”和“线性筛选”
- 那些年,我们一起参加过的高考
- 有关视图背景的设置方法
- 使用android杀蚊子
- 自己写的FPDF生成PDF
- 虚拟机 安装 ubuntu backtrack 5 上网设置
- 线性筛选素数。。。。线性哦
- Cocoa中NSString到NSDate的处理
- 局部特征(5)——如何利用彩色信息 Color Descriptors
- Java栈存储详解
- java 静态导入, import static
- jQuery Ajax 调用 WebService 返回数据表(DataTable)的方法
- Drupal 7 入门者很好的学习文档
- thread和Reference Counting内存管理造成的问题
- Antlr中skip()方法