数论初步之素数判断

基本数论-素数判断

一、暴力求解

  1、一个共识

         x = a*b且x = sqrt(x)*sqrt(x) => a==b==sqrt(x)或者a<sqrt(x) 且 b > sqrt(x),即要么a==b要么一个大于根号x一个小于根号x

     且a = x/b,那么我们只用判断小于sqrt(x)的数是否可以整除x即可。         

  2、暴力求法(O(n^(2/3)))

                

bool isPrime(int x){

for(int i=2;i<=sqrt(x);i++){

if(x%i==0) return false;

}

return true;

}

void getPrime(int x){

for(int i=1;i<=x;i++){

if(isPrime(i)) cout<<i;

}

}

  3、素数普通筛选(n*log(n))

    思想:任何一个素x = 素数*一个数,那么我们可以在找到一个素数的时候,再花n/i的时间去把现在可以确定不是素数的数给标记出来。

    如:已知2是一个素数那么:2,4,6,8,10,12...2*i都不是素数。

    那么时间复杂度为:n/2+n/3+n/5+......+n/p,p为小于n的素数那么渐进时间复杂度为O(n*log(n))

void getPrime(int x,int* primes){
    for(int i=2;i<=x;i++){
        if(primes[i]==0){
            for(int j=2;j*i<=x;j++)
                primes[j*i] = 1;
        }
    }
}

  4、素数筛选之线性筛选(o(n))

    由3我们可以知道,任何一个数字都可以有一个素数乘一个数得到。比如2是素数那么4,6,8,10,12,14,16....2*i都不是素数了,比如3是素数那么6,9,12,15...3*i都不是素数了,我们

    可以看出在我们标记不是素数的时候6,12等在2中标记过,在3中也被标记过这样一来就多了很多重复的操作,那么怎么去优化呢?

    我们最容易想到的就是在int j这个循环中加入,prime[j*i]!=1这个标志,就可以很容易的跳过多余的标记,那么我们总共标记了n个元素所以时间复杂度为O(N).

    

void getPrimeLine(int x,int* primes){
    for(int i=2;i<=x;i++){
        if(primes[i]==0){
            for(int j=2;j*i<=x&&primes[j*i]!=1;j++)
                primes[j*i] = 1;
        }
    }
}

   或者我们可以根据当前的已知的素数来标记如已知 1,2,3,5现在第6次标记就用1,2,3,5分别乘2,3,4,5,6这样每次乘出来的也不一样最终也不会重复标记,因而时间复杂度为O(N)

  

原文地址:https://www.cnblogs.com/jake9402/p/10199567.html

时间: 2024-08-01 19:07:29

数论初步之素数判断的相关文章

模板C++ 02数论算法 1最大公约数 AND 2素数判断

2.1最大公约数Greatest Common Divisor 补充知识:x*y=最小公倍数*最大公约数 int Euclid(int a,int b) { if(b==0) return a; return Euclid(b,a%b); } 2.2素数判断Prime #include<cmath> bool Prime(int n) { int t=sqrt(n); for(int i=2;i<=t;i++) if(n%i==0) return false; return true;

10.1数论初步

1.欧几里得算法(辗转相除法)和唯一分解定理: ①唯一性分解定理: 算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数均可写为质数的积,而且这些素因子按大小排列之后,写法仅有一种方式. 算术基本定理的内容由两部分构成: 分解的存在性: 分解的唯一性,即若不考虑排列的顺序,正整数分解为素数乘积的方式是唯一的. ②辗转相除法: 是求最大公约数的算法. 辗转相除法基于如下原理:两个整数的最大公约数等于其中较小的数和两数求余数的最大公约数.在这个过程中,较大的数缩小了,所以继续进行同样的计

POJ 1811 大素数判断

数据范围很大,用米勒罗宾测试和Pollard_Rho法可以分解大数. 模板在代码中 O.O #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; __int64 pri[]= {2,3,5,7,11,13,17,19,23,29,31};//用小素数表做随机种子避免第一类卡米

POJ1811 Prime Test(miller素数判断&amp;&amp;pollar_rho大数分解)

http://blog.csdn.net/shiyuankongbu/article/details/9202373 发现自己原来的那份模板是有问题的,而且竟然找不出是哪里的问题,所以就用了上面的链接上的一份代码,下面只是寄存一下这份代码,以后打印出来当模板好了. #pragma warning(disable:4996) #include <iostream> #include <cstring> #include <algorithm> #include <c

POJ3641 Pseudoprime numbers(快速幂+素数判断)

POJ3641 Pseudoprime numbers p是Pseudoprime numbers的条件: p是合数,(p^a)%p=a;所以首先要进行素数判断,再快速幂. 此题是大白P122 Carmichael Number 的简化版 /* * Created: 2016年03月30日 22时32分15秒 星期三 * Author: Akrusher * */ #include <cstdio> #include <cstdlib> #include <cstring&g

POJ 2262 Goldbach&#39;s Conjecture (素数判断)

Goldbach's Conjecture Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 37693   Accepted: 14484 Description In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conject

csu 1552: Friends(大素数判断+二分图)

1552: Friends Time Limit: 3 Sec  Memory Limit: 256 MB Submit: 525  Solved: 136 [Submit][Status][Web Board] Description On an alien planet, every extraterrestrial is born with a number. If the sum of two numbers is a prime number, then two extraterres

HDU 1695 GCD (数论-整数和素数,组合数学-容斥原理)

GCD Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output t

POJ2262_Goldbach&#39;s Conjecture【素数判断】【水题】

Goldbach's Conjecture Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 38024 Accepted: 14624 Description In 1742, Christian Goldbach, a German amateur mathematician, sent a letter to Leonhard Euler in which he made the following conjecture: