数论学习_素数测试

质数(prime number)又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数,这样的数称为质数。

对于判定质数,有一个很显然的方法就是判断除了1和他本身之外有没有其他的因数了。

1 bool ok(int N)
2 {
3    if(N==1) return 0;
4    for(int i=2;i<N;++i)
5         if(!N%i) return 0;
6    return 1;
7 }

但是有一个简单粗暴的优化方案是判断到sqrt(N)之内的因子就好了,因为因子是成对出现的,假如a是一个因子,那么N/a也是他的因子,显然当a=sqrt(N)时二者相等,如果再继续找到的因子a那么N/a一定出现在sqrt(N)之前,所以我们只判定到sqrt(N)即可。

 bool ok(int N)
 {
    if(N==1) return 0;
    int m=sqrt(n+0.5);
    for(int i=2;i<=m;++i)
           if(!N%i) return 0;
    return 1;
 }

但是对于大量素数的判定,如果还用这个判定法的话也会很耗时,这是筛法就派上用场了。筛法是一种简单检定素数的算法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratosthenes)。

筛法的思想也很简单,枚举所有的素数筛去他们所有的倍数的数(在求解范围之内),显然剩下的数都是素数。但其实,我们不必枚举所有的素数,枚举到sqrt(N)之内的素数即可,这样的正确性在于: 当我们枚举到一个素数x的时候,他的倍数有2,3......x-1,这些倍数如果是质数的话,因为小于x所以之前已经被筛过了,如果是合数根据算术分解定理:算术基本定理可表述为:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 N=P1a1P2a2P3a3......Pnan,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。所以也能分解出更小的质数,所以在之前也已经筛过。所以直接从x的x倍开始筛,

这样的缺点在于不能讲将所有的素数打表,但是能筛出一个判别数组,判定isp[i]是否为真。

 1 bool isp[MAXN];
 2 int   prime[MAXN], p = 0;
 3 void init(int N)
 4 {
 5     isp[0] = isp[1] = 1;
 6     for (int i = 2;;++i) {
 7         if (!isp[i]) {
 8             //prime[p++] = i;
 9             for (int j = i*i;j <= N;++j)
10                 isp[j] = 1;
11         }
12         if (i*i > N) break;
13     }
14 }

接下来说的就是一种线性筛法,欧拉筛法,不仅复杂度更低,还能将判别表和素数表都生成出来。

先上代码:

 1 bool isp[MAXN];
 2 int   prime[MAXN], p = 0;
 3 void init(int N)
 4 {
 5     isp[0] = isp[1] = 1;
 6     for (int i = 2;i <= N;++i)
 7     {
 8         if (!isp[i]) prime[++p] = i;
 9         for (int j = 1;j <= p&&i*prime[j] <= N;++j) {
10             isp[i*prime[j]] = 1;
11             if (i%prime[j] == 0) break;
12         }
13     }
14 }

首先这个方法真实运行起来不一定比埃式要快,因为有取模操作,但是他可以求解一些积性函数问题 ,这个以后再说。之所以说他是线性的是因为对于每个合数只会被他最小的质因子筛去一次。实现这一特性的就在于那句break语句。首先我们知道prime[]数组里的素数是递增的,如果i%prime[j]==0,则我们可以认为i=M*prime[j],

后面break掉的就是i*prime[k],他可以表示为M*prime[j]*prime[k],也就是说在后面他会被prime[j]筛掉,所以可以直接break。对于每个筛去的数i*prime[j],prime[j]都是这个数的最小质因子。

时间: 2024-10-22 17:13:03

数论学习_素数测试的相关文章

数论学习_欧拉函数

在数论,对正整数n,欧拉函数是小于n的正整数中与n互质的数的数目(φ(1)=1).此函数以其首名研究者欧拉命名(Euler'so totient function),它又称为Euler's totient function.φ函数.欧拉商数等. 例如φ(8)=4,因为1,3,5,7均和8互质. 从欧拉函数引伸出来在环论方面的事实和拉格朗日定理构成了欧拉定理的证明. 求解小于n且与n互素的整数个数.给出正整数n的唯一分解式: n=p1a1p2a2p3a3......pkak,求1,2,3.....

数论 - Miller_Rabin素数测试 + pollard_rho算法分解质因数 ---- poj 1811 : Prime Test

Prime Test Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 29046   Accepted: 7342 Case Time Limit: 4000MS Description Given a big integer number, you are required to find out whether it's a prime number. Input The first line contains the

HDu 2138 How many prime numbers 高效Miller素数测试

题目就是给出一组数,让我们测试其中有多少个是素数. 求素数有测试sqrt(n)个数的方法,有筛子方法,不过对于本题这样的题目来说就都不是高效的. 本题使用Miller Rabin素数测试法,效率奇高,对于不是极其大的整数测试都几乎是常数时间.令人神往的算法啊. 网上有个程序,好像是什么吉林的模板程序,不过我一直没看懂他是什么思路写的,是个AC的程序,不过却是错误的,呵呵,因为程序一直把9当做素数. 于是上网查找了其中原理,自己写了个程序,效率和他的差不多一样,通过时间基本无差别,不过我的思路是按

Miller-Rabin素数测试

算法实现原理:若p为素数,a^(p-1)≡1(mod p)  费马小定理 正确性:一次为75%,第T次为1-1/(4^T). 流程: 1.输入待判定的数N 2.循环 T>=10遍 1*. RAND一个数A<N,A=rand()%(n-2)+2,把它扔到快速幂中计算a^(N-1)%N 2*. 若答案等于1,通过测试,再试几组数据:否则,失败,退出测试 流程中涉及快速幂取模和 大数相乘取模------> 速度慢,若两数相乘大于十八位,仿照快速幂取模. (没有什么鬼二次探测定理,多算几次就好了

SQL学习_查询重复数据和连接多个表数据的方法

进行数据库测试时需要根据不同场景查询数据,以便验证发现的问题是否为脏数据引起的.记录一下最近常用的查询方法: 1. 查询表中重复数据(id不同,多个字段值相同) select P1.* from project as P1, project as P2 where P1.id<>P2.id and P1.ProjectId=P2.ProjectId and P1.ServiceTypeId=P2.ServiceTypeId and P1.Rank=P2.Rank 2.连接多个表数据 selec

Miller_Rabin素数测试算法模板对比

昨天在USACO做了一道判断素数的题,就想着学习一下Miller_Rabin素数测试算法,在网上找到两种模版,第一种十分简洁,运行速度也很快,但是会判错极少的几个非素数:第二种比较麻烦,运行速度很慢,所以我便想找到第一种模版不能判断的非素数特判一下,结果用了一天,电脑只找到10^8以下的,10^9内还有2个没找到,但正确的模版运行速度太慢,我的电脑又太渣,耗不起时间了,姑且先这样,等以后有深入理解有更好的方法再更新一下. 第一种:源自吉林大学ACM模版 刚开始用的是随机数测试,我想到以前了解过只

压缩跟踪(CT)代码详细学习_模块1(样本的采集和扩充)

本章主要详解的是compressive tracking框架中的第一部分:样本的采集和扩充部分. 在开始代码学习的前面,你需要知道的理论知识参见论文:Real-time Compressive Tracking.理论理解可以参见我的博客:http://blog.csdn.net/ikerpeng/article/details/19826409 . 这个模块中你需要知道一个基本的概念:代码里面几个变量指的是什么.上一张图: 也许你现在还不知道他们是什么,直接贴代码了.相信有我的注释你一定会懂的.

Miller-Rabin素数测试算法

由费马小定理可以知道,若p是素数且a是整数,则满足a^p==a(mod p).若存在正整数a不满足a^p==a(mod p),那么n是合数. 定义:令a是一个正整数,若p是合数且满足a^p==a(mod p),则p称为以a为基的伪素数. Miller-Rabin素数测试算法原理: 假如p是素数,且(a,p)==1,(a为任意小于p的正整数),那么a^p-1==1(mod p).如果a^p-1==1(mod p), 则可认为n是素数,取多个底进行试验,次数越多,n为素数概率越大.(我的个人理解多次

HDU2138 随机素数测试 Miller-Rabin算法

题目描述 Give you a lot of positive integers, just to find out how many prime numbers there are.. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 32-bit signed integer, and each of them won’t be