素数定理

质因数分解的rho以及miller-rabin

為{幸葍}努か 提交于 2020-04-04 06:10:55
一、前言 质因数分解,是一个在算法竞赛里老生常谈的经典问题。我们在解决许多问题的时候需要用到质因数分解来辅助运算,而且质因数分解牵扯到许许多多经典高效的算法,例如miller-rabin判断素数算法,rho启发式搜索质因数分解算法等。在此文里,我要介绍的就是miller-rabin算法以及rho启发式搜索分解算法。 二、算术基本定理 首先,我们得知道,任意一个大于1的自然数都可以分解为有限个质数的乘积。这里因子均为质数,且为正整数。我们把这样的分解成为N的标准分解式。关于算数基本定理的应用有许多,例如可以证明素数无限,定义god,lcm等,在此不一一赘述。有了算数基本定理,我们可以发现计算数论函数,约数和等都是十分方便的,这大大的方便了我们的解题。接下来我们介绍如何来分解质因数。 三、质因数分解的算法 所谓质因数,是某自然数的因素而且这个因素还得是质数。 我们不难想到基本的枚举,即暴力枚举1~n所有数,判断是否能够被n整除且该数是否为质数。大概代码如下: For i:=1 to n do If n mod i=0 then If check(i) then //check为检验i是否为质数的子函数,返回值为boolean Writeln(i); Function check(n:longint):boolean; Var i:longint; begin For i:=2 to n

《信息安全数学基础一》第一章笔记

被刻印的时光 ゝ 提交于 2020-03-26 03:15:25
《信息安全数学基础一》第一章笔记 目录 《信息安全数学基础一》第一章笔记 整除 素数,合数 素数判别 筛法 埃式筛 欧拉筛 进制转换 最大公因数与最小公倍数 欧几里得算法 贝祖等式 拓展欧几里得算法 算术基本定理 整除 定义 在整数域内,若 \(a = q\cdot b\) ,则 \(b\) 整除 \(a\) ,记作 \(a | b\) 性质 若 \(a | b,\ b | c\) ,则 \(a | c\) 若 \(c | a_{i},\ i = 1,\ 2,\ ..,\ n\) 则 \(c\) 也整除 \(a_{i}\) 的线性组合 素数,合数 素数定义 除了 \(1\) 和自身外,没有因数的数,称之为素数,也称为质数,其他数被称为合数。 \(2\) 是最小的素数 素数判别 一个定理 对于合数 \(n\) ,必然存在不超过 \(\sqrt{n}\) 的质因子。 设 \(n = pq\) ,设 \(p\) 是最小因子,则 \(p\leq q\) 则 \(n = pq \geq p^{2}\) 所以 \(p\leq \sqrt{n}\) 假设 \(p\) 是合数,则可以继续进行分解,与题设不符,所以 \(p\) 是质数。 定理推论 对于一个数 \(n\) ,若其不存在不超过 \(\sqrt{n}\) 的质因子,那么其为素数。 素数平凡判别 枚举 \(2-\sqrt{n}\) 内的素数

Divisors(约数的数目)

 ̄綄美尐妖づ 提交于 2020-03-03 10:27:59
UVA294 题目要求指定范围内约数数目最多的数以及对应的约数数量。 根据唯一分解定理,对于任意正整数 2 ≤ N 2\leq N 2 ≤ N ,有: N = ∑ i = 1 n p i a i , p 为 素 数 N=\sum\limits_{i=1}^{n}p_i^{a_i},p为素数 N = i = 1 ∑ n ​ p i a i ​ ​ , p 为 素 数 那么根据乘法原理,约数的总数目为: f ( N ) = ∏ i = 1 n ( 1 + a i ) f(N)=\prod\limits_{i=1}^{n}(1+a^i) f ( N ) = i = 1 ∏ n ​ ( 1 + a i ) # include <iostream> # include <algorithm> # include <cmath> # include <vector> using namespace std ; const int MAXN = 1000001 ; int main ( ) { int T ; cin >> T ; int Left , Right ; while ( T -- ) { cin >> Left >> Right ; int Ans = 0 , Node = Left ; for ( int n = Left ; n <= Right ; ++ n ) { int

筛法求素数的几个模板

て烟熏妆下的殇ゞ 提交于 2020-02-23 11:23:17
定义法 素数可以由定义法求出,即遍历2到sqrt(x)中是否存在能整除x的数,如果存在则不是素数,如果不存在,则是素数,复杂度是O(n)。在数据量小的时候可以使用。 bool isprime(int x) // 判断素数 { if ( x<=1 ) return false; for (int i = 2; i*i<=x; i++) if (x%i==0) return false; return true; } 一般线性筛法 当数量级变大时,如果要找出某个范围内的素数,那么时间复杂度很容易过不去。因此考虑这样一个命题: 若一个数不是素数,则必然存在一个小于它的素数作为其因数。 该命题很容易证明其正确性 所以我们假设已经获得小于一个数x的所有素数,那么判断时就只需要看x是否能被这些素数整除,来判断x是不是素数。 但这样依然需要大量的枚举测试工作,因此换一个角度:当获得一个素数时,即将他所有的倍数均标记为非素数。这样一来,遍历是,如果这个数没有被标记,就说明它就无法被小于它的书整除,则可以认定为素数。 #define MAXSIZE 10001 int Mark[MAXSIZE]; int prime[MAXSIZE]; //判断是否是一个素数 Mark 标记数组 index 素数个数 int Prime(){ int index = 0; memset(Mark,0,sizeof

米勒拉宾素数检测

三世轮回 提交于 2020-02-17 14:11:21
是一种随机化素数检测算法 基于下面的定理 费马小定理:如果p是素数,a不是p的倍数,那么 \(a ^ {p - 1} \equiv 1(\mod \ p)\) 二次探测定理:如果p是一个素数,且x∈[1,p - 1],则方程 \(x ^2 \% p = 1\) 的解为 \(x = 1\) 或 \(x = p - 1\) 费马小定理的逆命题:如果 \(a^{p - 1} \equiv 1(\mod\ p)\) 成立,那么p是一个素数且a不是p的倍数 可以确定费马小定理的逆命题不一定成立。 那么对于一个数,如果不满足 \(a ^ {p - 1} \equiv 1(\mod \ p)\) 那么一定不是素数,如果满足,那么有可能是素数,取a = [1,p)的随机数,在进行判断,进行几次即可,则为素数的可能性越大 但是对于卡迈克尔数, \(卡迈克尔数是一个合数p,a不是p的倍数,但符合a^{p - 1}\equiv 1(\mod \ p)\) 则需要每次判断费马小定理时,进行二次探测,排除卡迈克尔数 算法 当p为2时为素数 当p小于2或偶数时不是素数 10次检测,随机化 \(a∈[1,p)\) 求出 \(a^u \% n\) ,然后二次探测判断 其中进行优化,使得进行二次探测时的幂小一点,然后在慢慢扩大,不然,如果直接计算p - 1次幂,可能会造成溢出的情况 #include

约数——反素数

时间秒杀一切 提交于 2020-02-10 15:13:22
反素数 对于任何正整数x,其约数的个数记作g(x),例如g(1)=1、g(6)=4。 如果某个正整数x满足:对于任意的小于x的正整数 i,都有g(x)>g(i) ,则称x为反素数。 例如,整数1,2,4,6等都是反素数。 现在给定一个数N,请求出不超过N的最大的反素数。 输入格式 一个正整数N。 输出格式 一个整数,表示不超过N的最大反素数。 数据范围 1 ≤ N ≤ 2 ∗ 1 0 9 1≤N≤2∗10^9 1 ≤ N ≤ 2 ∗ 1 0 9 输入样例: 1000 输出样例: 840 题解: 我们推的反素数其实一个1-n中含有最多约数,并且这个数最小的数字。 假设这个数为x,我们画一个数轴来看,因为要任意的小于x的正整数 i,所以x点右边的数不考虑。再看左边的数,约数个数都是小于等于f(x)但是都是小于x的。 这里有几个性质: 1, 2 ∗ 1 0 9 2*10^9 2 ∗ 1 0 9 中约数个数最多的数一共有1600个约数。 2, 2 30 > 2 ∗ 1 0 9 2^{30}>2*10^9 2 3 0 > 2 ∗ 1 0 9 3,利用中国四大定理可以知道。我们分解质因子再看看题目范围最多用到9个质因子就会超过范围了。 4,我们分解质因子的时候我们的因子指数是递减的。 所以综上,我们可以使用爆搜来处理问题。 # include <bits/stdc++.h> using

素数算法大全

拥有回忆 提交于 2020-02-01 05:18:44
注意: 如果没有特殊说明, 以下讨论的都是针对n为素数时的时间复杂度 1. 根据概念判断: 如果一个正整数只有两个因子, 1和p,则称p为素数. 代码: bool isPrime(int n) { if(n < 2) return false; for(int i = 2; i < n; ++i) if(n%i == 0) return false; return true; } 时间复杂度O(n). 2. 改进, 去掉偶数的判断 代码: bool isPrime(int n) { if(n < 2) return false; if(n == 2) return true; for(int i = 3; i < n; i += 2) if(n%i == 0) return false; return true; } 时间复杂度O(n/2), 速度提高一倍. 3. 进一步减少判断的范围 定理: 如果n不是素数, 则n有满足1<d<=sqrt(n)的一个因子d. 证明: 如果n不是素数, 则由定义n有一个因子d满足1<d<n. 如果d大于sqrt(n), 则n/d是满足1<n/d<=sqrt(n)的一个因子. 代码: bool isPrime(int n) { if(n < 2) return false; if(n == 2) return true; for(int i = 3;

求素数算法-网摘

自闭症网瘾萝莉.ら 提交于 2020-02-01 04:10:42
摘自: http://www.cnblogs.com/luluping/archive/2010/03/03/1677552.html 浅析求素数算法 注意: 如果没有特殊说明, 以下讨论的都是针对n为素数时的时间复杂度 1. 根据概念判断: 如果一个正整数只有两个因子, 1和p,则称p为素数. 代码: bool isPrime(int n) { if(n < 2) return false; for(int i = 2; i < n; ++i) if(n%i == 0) return false; return true; } 时间复杂度O(n). 2. 改进, 去掉偶数的判断 代码: bool isPrime(int n) { if(n < 2) return false; if(n == 2) return true; if(n%2==0) return false; for(int i = 3; i < n; i += 2) if(n%i == 0) return false; return true; } 时间复杂度O(n/2), 速度提高一倍. 3. 进一步减少判断的范围 定理: 如果n不是素数, 则n有满足1<d<=sqrt(n)的一个因子d. 证明: 如果n不是素数, 则由定义n有一个因子d满足1<d<n. 如果d大于sqrt(n), 则n/d是满足1<n/d<

浅析求素数算法

那年仲夏 提交于 2020-02-01 04:09:26
浅析求素数算法 转载: http://www.linuxsir.org/bbs/showthread.php?t=278294 注意: 如果没有特殊说明, 以下讨论的都是针对n为素数时的时间复杂度 1. 根据概念判断: 如果一个正整数只有两个因子, 1和p,则称p为素数. 代码: 1 bool isPrime(int n)2 {3 if(n < 2) return false;4 for(int i = 2; i < n; ++i)5 if(n%i == 0) return false;6 return true;7 } 时间复杂度O(n). 2. 改进, 去掉偶数的判断 代码: bool isPrime(int n) { if(n < 2) return false; if(n == 2) return true; for(int i = 3; i < n; i += 2) if(n%i == 0) return false; return true;} 时间复杂度O(n/2), 速度提高一倍. 3. 进一步减少判断的范围 定理: 如果n不是素数, 则n有满足1<d<=sqrt(n)的一个因子d. 证明: 如果n不是素数, 则由定义n有一个因子d满足1<d<n. 如果d大于sqrt(n), 则n/d是满足1<n/d<=sqrt(n)的一个因子. 代码: bool isPrime

素数问题

安稳与你 提交于 2020-01-25 01:25:46
如何判断一个数是否为素数 暴力方法 判断一个数n是否为素数,只需在(1,n)看是否存在它的因子 bool IsPrime(int n) { if(n < 2) return false; else if(n == 2) return true; else{ for(int i = 2;i < n;++i) if(n % i == 0) return false; return true; } } 优化版1 定理 :如果n是合数,在 \((1,\sqrt{n}]\) 必定存在它的因子 证明:设 \(n=ab\) 假设a,b都小于 \(\sqrt{n}\) ,那么 \(ab<\sqrt{n}\sqrt{n}=n\) ,矛盾 假设a,b都大于 \(\sqrt{n}\) ,那么 \(ab>\sqrt{n}\sqrt{n}=n\) ,矛盾 因此我们可以得知,只需在 \((1,\sqrt{n}]\) 中看是否存在它的因子即可,再者可先判断n是否为偶数(2除外),不是偶数的话,只需在 \((1,\sqrt{n}]\) 中的奇数看是否存在它的因子即可 bool IsPrime(int n) { if(n < 2) return false; else if(n == 2) return true; else if(!(n&1))//n是偶数 return false; else { int num