素数

【C++】欧拉素数筛的理解与实现

独自空忆成欢 提交于 2019-11-29 11:58:28
在传统的素数筛法中,我们使用了对于每一个数n,在 1~(√n) 范围内进行取模检查,这样逐一判断的复杂度为n(√n)。 但如果我们需要更快的筛法时怎么办? 于是著名的 欧拉筛 诞生了。它能将复杂度降为 O(n) 级别。 1.关键理解: 欧拉筛的原理是保证在 2~n 范围中的每一个合数都能被 唯一分解成它的最小质因数与除自己外最大的因数相乘的形式 。因此我们枚举2~n中的每一个数作为筛法中的“除自己外的最大因数”,如果它未被标记为合数,就先将它放入素数表内,再将这个最大因数与素数表中已经找到的素数作为最小质因数相乘,将得到的这些数标记为合数。最后输出得到的素数表即可。 但是我们如何保证 每个合数都被唯一分解 ? 解决方法如下: 当此时取出的素数表中的素数(即枚举的最小质因子)整除于当前枚举的合数时,我们就停止循环素数表,开始枚举下一个合数。 证明如下: 设当前枚举的最小质因子prime[i]整除于合数n时,即我们要筛掉合数 n*prime[i] ;如果我们此时不退出,继续枚举下一个素数prime[i+1],对于将要筛掉的合数 n*prime[i+1] 由于插入顺序从小到大,则 prime[i+1]>prime[i] 。由于prime[i]整除于合数n,所以必然合数 n*prime[i+1] 还可以被分解为 $$ (\frac n {prime[i]} prime[i+1])

AK acm/oj.筛选法求素数

你。 提交于 2019-11-29 04:49:32
题目描述 用筛选法求100之内的素数,并输出。 样例输入 无 样例输出 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 示例代码 # include <bits/stdc++.h> using namespace std ; int main ( ) { int n [ 100 ] ; for ( int i = 0 ; i < 100 ; i ++ ) n [ i ] = i + 1 ; n [ 0 ] = 0 ; for ( int i = 0 ; i < 100 ; i ++ ) { if ( n [ i ] == 0 ) continue ; for ( int j = i + 1 ; j < 100 ; j ++ ) { if ( n [ j ] % n [ i ] == 0 ) n [ j ] = 0 ; } if ( n [ i ] != 0 ) cout << n [ i ] << " " ; } return 0 ; } 来源: CSDN 作者: AK-大菜鸡 链接: https://blog.csdn.net/qq_16525829/article/details/103244531

筛选法获取素数列表

浪子不回头ぞ 提交于 2019-11-28 22:46:38
获取n以内素数列表 使用筛选法,生成正整数n以内素数列表。 算法描述: 初始设置BitSet从0到n的值均为true。 从2开始,由于2是素数,所以将所有2的倍数排除;然后下一个素数是3,则将所有3的倍数排除;下一个素数是 5,将所有5的倍数排除… 以此类推,直到n。 BitSet中剩余的值为true的index即为素数。 具体代码: /** * 筛选法生成正整数n以内素数列表 * 描述: * 初始设置BitSet从0到n的值均为true * 从2开始,由于2是素数,所以将所有2的倍数排除 * 然后下一个素数是3,则将所有3的倍数排除 * 下一个素数是5,将所有5的倍数排除 * ... * 直到n * BitSet中剩余的值为true的index即为素数 * * @param n 正整数 * @return 素数表,用 BitSet 表示 */ public static BitSet genPrimeBitSet ( int n ) { BitSet primeBitSet = new BitSet ( n ) ; primeBitSet . set ( 0 , n , true ) ; primeBitSet . set ( 0 , false ) ; primeBitSet . set ( 1 , false ) ; for ( int i = 2 ; i <= n ; i

C语言作业I博客作业05

房东的猫 提交于 2019-11-28 22:25:45
C语言I博客作业05 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-1/homework/9825 我在这个课程的目标是 学会自定义一个函数,了解其基本用法 这个作业在那个具体方面帮助我实现目标 自定义函数的使用,阶乘函数的编译 参考文献 《C语言程序设计》《PTA实验指导》百度百科 1.PTA实验作业 1.1 水仙花数判断 题目内容描述 本题要求实现一个函数,判断任一整数是否为水仙花数(必须是三位数,且数的每一位上数字的立方和与数本身相等)。例如153=1^3+5^3+3^3=1+125+27=153,而1或155则不是水仙花数。如果是水仙花数,则函数返回1,否则返回0. 函数接口定义: int func(const int N); 其中N是用户传入的参数。N的值不超过int类型的范围。如果参数N是水仙花数,则返回1,否则返回0。 1.1.1数据处理 数据表达:用了sum和x等整形变量,给x定义赋值。 数据处理:表达式为sum += (x % 10) * (x % 10) * (x % 10),开始输入n,通过函数func,判断是否为是否为素数,是则输出1,否则输出0. 函数参数:主调函数的名称main,被调函数的名称func,被调函数的类型为整型,为形参。 1.1

素数筛选

限于喜欢 提交于 2019-11-28 22:10:25
简单的引入一下欧拉函数 素数筛选知道4种,暴力筛(逐个判断),埃拉特斯特尼筛 ,欧拉线性筛 ,一个大于5的素数一定在6的倍数周围(PS:不知道官方名是什么) 埃拉特斯特尼筛法。时间复杂度为O(n loglog n) //倍数筛除 时间复杂度(o(nloglogn) //一个素数的倍数一定不是素数 int vis[1000] , prime[1000]; void judge() { memset(vis,1,sizeof(vis)); int cnt=0; prime[0] = prime[1] = 0; for(int i=2;i<1000;i++) { if(vis[i]) { prime[cnt++] = i; //cout<<prime[cnt-1]<<endl; for(int j=i*i;j<1000;j+=i) vis[j] = 0; } } } 欧拉线性筛法 时间复杂度(o(n) ) //欧拉线性筛法 时间复杂度(o(n)) const int MAXN=3000001; int prime[MAXN];//保存素数 bool vis[MAXN];//初始化 void Prime(int n) { int cnt=0; memset(vis,1,sizeof(vis)); for(int i=2;i<=n;i++) { if(vis[i]) { prime[cnt+

2019 杭电多校 第三场

99封情书 提交于 2019-11-28 21:51:31
2019 Multi-University Training Contest 3 补题链接: 2019 Multi-University Training Contest 3 1002 Blow up the city (HDU-6604) 题意 给定 \(n\) 个点和 \(m\) 条边的有向无环图,给出 \(q\) 次询问,每个询问给出 \(a\) 和 \(b\) ,求有多少个点,满足该点删去后 \(a\) 和 \(b\) 中至少一个点不能到达出度为 \(0\) 的点。 题解 支配树/灭绝树 拓扑排序 最近公共祖先 1006 Fansblog (HDU-6608) 题意 给定素数 \(\ P(1e^9\leq P\leq 1e^{14})\) ,试找出小于 \(P\) 的最大素数 \(\ Q\) ,求出 \(\ Q! \ mod \ P\) 。 题解 威尔逊定理 逆元 质数的密度分布 Miller-Rabin素数测试 威尔逊定理:当且仅当 \(P\) 为素数时: \((P - 1)!\equiv -1\ mod\ P\) 即 \((P-1)!\equiv(P-1)\ mod\ P\) ,由于 \((P - 1)! = (Q!) * (Q + 1) * (Q + 2) * ... * (P - 1)\) ,可得 \(Q!\ mod\ P=\frac {(P - 1)}{(Q +

孪生素数

倾然丶 夕夏残阳落幕 提交于 2019-11-28 21:49:17
# include <stdio.h> # include <stdlib.h> # include <math.h> int prime ( int a ) { int i ; for ( i = 2 ; i < a - 1 ; i ++ ) { if ( a % i == 0 ) return 0 ; } return 1 ; } void main ( ) { int a = 2 , n = 0 ; while ( n < 15 ) { if ( prime ( a ) && prime ( a + 2 ) ) { n ++ ; printf ( "%d,%d\n" , a , a + 2 ) ; } a ++ ; } system ( "pause" ) ; } 来源: CSDN 作者: Nabandon 链接: https://blog.csdn.net/Nabandon/article/details/103244388

0.0

孤街浪徒 提交于 2019-11-28 21:33:10
---恢复内容开始--- 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 C语言I—2019秋作业05 我在这个课程的目标是 更加深层次了解C语言 这个作业在那个具体方面帮助我实现目标 实践动手能力 参考文献 Markdown基本语法 1PTA作业 1代码互评 水仙花数判断:本题要求实现一个函数,判断任一整数是否为水仙花数(必须是三位数,且数的每一位上数字的立方和与数本身相等)。例如153=1^3+5^3+3^3=1+125+27=153,而1或155则不是水仙花数。如果是水仙花数,则函数返回1,否则返回0. 我的代码 同学代码 我的代码是先求出来百位,十位,个位数字后,在进行立方和相加。 他是利用循环求余一次循环求一个值的3次方 我的代码改四位数的话新增一个变量 例如 q q/=1000 能求千位上的数字 以此类推 1 .1判断一个整数的各位数字平方之和能否被5整除 编写函数fun,其功能是:判断一个整数的各位数字平方之和是否被5整除,可以被5整除则返回1,否则返回0 1.1.1数据处理 数据表达:定义了整形变量ans,用ans += (n%10)*(n%10)计算一个整数的个位数字平方之和。 数据处理:主调函数的名称main,被调函数的名称fun,被调函数的类型为整型。 1.1.2实验代码截图 1.1.3造测试数据 输入数据 输出数据 说明 35 0

对 黎曼猜想 的 简单 看法

a 夏天 提交于 2019-11-28 20:48:02
这 是 我在 一个 帖子 里的 回复 , 原帖地址 : 《千年难题——七个悬赏1000000美元的数学问题》 http://tieba.baidu.com/p/6235630502 , 我的 回复 如下: 黎曼猜想 其实 根本 不用 证明, 现在有 很多 定理 都是 以 黎曼猜想 为 基础 推导出来的, 这些 定理 都 在 用, 用的好好的, 所以 现在的 问题 不是 证明 黎曼猜想 , 而是 用 黎曼猜想 能 干什么, 比如 知道 素数 的 分布? 我想 并不能 精确 的 知道 素数 的 分布, 那 能不能 根据 黎曼猜想 判断 一个 大数 是否 是 素数 ? 我想也不能, 哥德巴赫猜想 说 一个 偶数 可以 表示为 2 个 素数 的 和, 那 给定 一个 偶数, 根据 黎曼猜想 能 求得 和 为 该 偶数 的 所有 素数对 吗? 我想也不能 。 那 证明 黎曼猜想 有什么用? 所以 问题 的 重点 在于 黎曼猜想 能 用来 做什么, 只要 黎曼猜想 能 用来 解决问题 , 先用着 就 行了 。 如果 黎曼猜想 不能 解决 某个 问题, 那 把 黎曼猜想 证明了 也没用, 还是 不能 解决这个问题 。 来源: https://www.cnblogs.com/KSongKing/p/11427333.html

Comet OJ - Contest #9 & X Round 3B

為{幸葍}努か 提交于 2019-11-28 17:22:29
Comet OJ - Contest #9 & X Round 3B 其实这个题我一开始,完全⑧会. 题目里给了个关于素数的定理,就考虑一下素数在这题里扮演什么样的角色. 然后你发现,如果他第 \(0\) 天告诉了一个素数,那么只需要一天所有人就都知道了. 如果是一个合数,那么第一天所有素数会知道消息,第二天所有人就都知道了. 需要注意的是,要考虑它第 \(0\) 天告诉一个素数时,如果这个素数的倍数也在这个区间内,是需要两天的. \(Code:\) #include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <string> #include <vector> #include <queue> #include <cmath> #include <ctime> #include <map> #include <set> #define MEM(x,y) memset ( x , y , sizeof ( x ) ) #define rep(i,a,b) for (int i = a ; i <= b ; ++ i) #define per(i,a,b) for (int i = a ; i >= b ; -- i) #define