求解第N个素数

  这个题目是现代软件工程老师布置的一个个人项目,当看到这个题目第一个想到的就是筛法。然而仔细考虑下,筛法的信息冗余量实在太大,我要求第N个素数,却把前N个素数都求了出来,那有没有一个直接能求解第N个素数是什么的方法呢?答案当然是。。。没有。但是,有一种方法用迭代的方法能够求解π(x),即是0~x中素数的个数,它就是梅塞尔—勒梅尔公式,黑科技一般的公式。具体这个公式是什么样的,贴出来太麻烦,可以去wiki看一下,搜索素数计数函数即可(中文版需FQ)。

  把这个问题搞定后,怎么求得第N个素数呢?显然当N小于梅塞尔—勒梅尔准备素数的个数时,直接从数组调取即可。当N很大时,我们可以用近似比例微分(PD)的调节方式来使π(x)快速逼近N,这里D项的系数可以参照素数在不同数量级大致的分布密度,P项系数可以默认为1。然而问题还没有解决,一方面是PD调节在系数不是很完美的情况下会出现在目标值附近震荡的情况,另一方面就是即恰好π(x)为N,也不能确定x就是第N个素数。对于第一个方面,由于D项的系数是跟密度相关的,是比较可信的,即使可能最后不恰好与目标值相同,但相差绝对不会很大,这就可以让其误差小于很小的一个整数时停止,比如3,接下来直接跨过偶数,调用公式直至与N相同。第二个方面其实也很简单,x为第N个素数,只需要π(x)=N,π(x-1)=N-1即可,解决这个问题可以用两种方法,一种继续套用公式递减直至满足条件即可,另一种是递减判断出第一个素数为止,这里可以用米勒罗宾算法,不过这两种方法在N较小时相差不大,N较大时后者会有一定的优势。

  以下是耗费时间,具体代码参见https://github.com/WBinke/PrimeFinder

  

时间: 2024-12-20 14:56:23

求解第N个素数的相关文章

Python练习题 035:Project Euler 007:第10001个素数

本题来自 Project Euler 第7题:https://projecteuler.net/problem=7 # Project Euler: Problem 7: 10001st prime # By listing the first six prime numbers: # 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. # What is the 10 001st prime number? # Answer

【算法】普通方法和筛选法求素数

素数指的是因子只有1和本身的数(1不是素数),求解素数在数学上应用非常广泛,而求解n以内的素数也是我们编程时常遇到的问题,在这个问题上,筛选法求解素数运行得非常快.下面首先介绍如何判断一个是不是素数,然后介绍用普通方法求n以内的素数,接着是筛选法求n以内的素数,最后是两种算法的运行时间比较 判断一个数是不是素数 算法思想:判断小于等于一个数的平方的所有大于1的整数是不是能整除这个数,如果能,则表明这个数不是素数:反之,则是素数. //判断一个数是否为素数 bool isPlain(int val

『素数(Prime)判定和线性欧拉筛法(The sieve of Euler)』

素数(Prime)及判定 定义 素数又称质数,一个大于1的自然数,除了1和它自身外,不能整除其他自然数的数叫做质数,否则称为合数. 1既不是素数也不是合数. 判定 如何判定一个数是否是素数呢?显然,我们可以枚举这个数的因数,如果存在除了它本身和1以外的因数,那么这个数就是素数. 在枚举时,有一个很简单的优化:一个合数\(n\)必有一个小于等于\(\sqrt{n}\)的因数. 证明如下: 假设一个合数\(n\)没有小于等于\(\sqrt{n}\)的因数. 由于\(n\)为合数,所以除了\(n\)与

判断10000000以内素数的方法---进化过程

一:暴力求解(直接根据素数的定义) //返回1:是素数:返回0:非素数 int isPrime(int n){ int i; if(n<2) return 0; for(i=2;i<n;i++) if(n%i==0) return 0; return 1;} 然而想要通过此方法快速获得10000000以内的素数总数的话,难......二:除去部分因数求解(平方根和偶数助力) 首先,能被2整除的数----非素数: 其次,举例数36,开方得6.好,我们来看看25可以分解成哪些因数. 正序来看,36

Lucas定理

求解大组合数对素数(不大于100000)取模的结果..题目还没做出来,先把模板记着了. ll fac[maxn], inv[maxn]; ll pow_mod(ll a, int n, int mod) { ll ret = 1; while (n) { if (n&1) ret = ret * a % mod; a = a * a % mod; n >>= 1; } return ret; } void init(int n) { fac[0] = 1; for (int i = 1

PE5 Smallest multiple

题目 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder. What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20? https://projecteuler.net/problem=5 分析 可以将题

刘汝佳 例题10-3 选择与除法

1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<vector> 5 #include<iostream> 6 using namespace std; 7 8 const int maxn = 10000; 9 vector<int> primes; 10 int e[maxn]; 11 12 /** 13 add_factorial(int n,

Diffie-Hellman秘钥交换算法

DH算法是第一个公钥方案 使用在一些常用安全协议或产品(例如SSH等) 密钥交换方案 不能直接用于有大量数据传输的保密通信 允许两个用户可以安全地建立一个共享的秘密信息,用于后续的通讯过程 该秘密信息仅为两个参与者知道 算法的安全性依赖于有限域上计算离散对数的问题 DH算法 通信双方/多方选择大素数P,以及p的一个原根a 用户A选择一个随机数Xa≤p,计算Ya=aXa mod p 用户B选择一个随机数Xb≤p,计算Yb=aXb mod p 每一方保密X值,而将Y值交换给对方 即:X是私钥,Y是公

(素数求解)I - Dirichlet&#39;s Theorem on Arithmetic Progressions(1.5.5)

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description If a and d are relatively prime positive integers, the arithmetic sequence beginning with a and increasing by d, i.e., a, a + d, a + 2d, a + 3d, a