最小质数

素数筛

柔情痞子 提交于 2020-03-29 15:51:59
1.(nlogn): bool not_prime[2333]=false; //把非质数都设为false,如果not_prime为false,则是质数,为true,则不是质数 not_prime[1]=true; for(int a=2;a<=n;a++) for(int b=a+a;b<=n;b+=a) not_prime[b]=true; //是a的倍数的数b全部是非质数,即not_prime[b]=true; /*b从2a开始,每次+a,直到题目给定的范围n结束 a=2的时候,b一共+n/2次 a=3的时候,b一共+n/3次 ... a=n的时候,b一共+n/n次 那么整体时间复杂度就是: n*(n/2+n/3+...+n/n) ≈n*(n/1+n/2+n/3+...+n/n) ≈nlogn 注:n/1+n/2+n/3+...+n/n为调和级数,其值约为logn,有兴趣自查*/ /*我们知道,筛4的时候,4的倍数已经在2中筛完了 筛6的时候,6的倍数已经在3中筛完了 以此类推,合数的倍数将在前面筛完了 那么我们就有如下小优化:*/ bool not_prime[2333]=false; not_prime[1]=true; for(int a=2;a<=n;a++) if(not_prime[a]==false) for(int b=a+a;b<=n;b+=a) not

0x31 质数

那年仲夏 提交于 2020-03-09 15:23:45
质数 定义: 若一个大于1的数的因数只有1和它本身,那么称该数为质数(素数),否则称其为合数。 素数分布定理 设 \(x≥1\) ,以 \(π(x)\) 表示不超过 \(x\) 的素数的个数,当 \(x→∞\) 时, \(π(x)~x/ln(x)\) 。 质数的判定(试除法) 定理: 若一个数 \(N\) 为合数,则 \(N\) 必存在一个大于 \(1\) 小于等于 \(\sqrt N\) 的因数。 证明:假设 \(N\) 不存在小于等于 \(\sqrt N\) 的因数。 按定义, \(N\) 至少存在一个大于1小于 \(N\) 的因数,记该数为 \(a\) . 那么 \(N = a * x\) ,其中 \(x = N / a\) 。 若 \(a\) 和 \(x\) 均大于 \(\sqrt N\) ,那么$ a * x > N$,与前面矛盾,故假设不成立。 bool is_prime(int n) { if (n < 2) return false; int k = sqrt(n); for (int i = 2; i <= k; i++) if (n % i == 0) return false; return true; } 例1. 房间里面有 \(N\) 盏关着的灯,编号依次为 \(1,2, 3,。。。,N\) ,有 \(N\) 个人,他们的编号也依次为 \(1,2, 3,。

「min_25筛」

房东的猫 提交于 2020-02-29 07:59:00
min25_筛是一种用于快速求出一种积性函数的筛法. 它的使用有三个条件: 1.必须是积性函数 2.必须是低阶多项式的形式 3. \(p^j\) 的函数值能够快速求出,不一定是 \(O(1)\) . 首先定义 \(g(n,j)\) 表示[1,n]中最小质因子 \(>p_j\) 或者它是质数,满足两条件之一 \(i\) 的 \(i^k\) (低阶多项式那一部分?)的和. \(g(n,j)=\sum_{i=1}^n[min\ p>p_j|i\in P]i^k\) \(g(n,0)=\sum\limits_{i=2}^ni^k\) 转移的话分为 \(p_j^2<=n\) , \(p_j^2>n\) . 1.若 \(p_j^2\) >n,则不可能存在一个合数满足 \(min\ p>p_j\) ,所以 \(g(n,j)=g(n,j-1)\) 2. \(p_j^2\) <=n. 考虑从 \(g(n,j-1)\) 移动到 \(g(n,j)\) 的损失必定是 \(min\ p==p_j\) 的那些数的函数值. \(g(n,j)=g(n,j-1)-p_j^k(g(\frac{n}{p_j},j-1)-\sum\limits_{i=1}^{j-1}p_i^k)\) 所以 \[ g(n,j)=\begin{cases} g(n,j-1)&p_j^2>n\\ g(n,j-1)-p_j^k(g(\frac

「笔记」$Min\\_25$筛

旧街凉风 提交于 2020-02-16 21:53:06
总之我也不知道这个奇怪的名字是怎么来的。 \(Min\_25\) 筛用来计算一类积性函数前缀和。 如果一个积性函数 \(F(x)\) 在质数单点是一个可以快速计算的关于此质数的多项式。 那么可以用 \(Min\_25筛\) 。 这个东西和质数关系很大。 我们考虑分开处理质数和非质数的贡献。 首先处理质数: 设, \(R(n)\) 为 \(n\) 的最小质因子, \(P\) 为质因子集合, \(p_i\) 为从小到大第 \(i\) 个质数。 \(\forall\ x\in P,F(x)=x^k\) 。 设: \[g(n,j)=\sum\limits_{i=1}^{n}i^k[i\in P||R(i)>p_j]\] 那么转移: 如果当前 \(p_j^2>n\) ,因为最小的含有 \(p_j\) 的合数是 \(p_j^2\) ,所以没有贡献需要减掉。 那么: \[g(n,j)=g(n,j-1)\] 如果当前 \(p_j^2<=n\) ,这个时候要减掉一些贡献了。 这些贡献是 \(p_j\) 所带来的,而这个时候左右 \(R(i)=p_j\) 的贡献都需要被减掉。 考虑求出这部分的贡献。 那么显然是对于其所能达到的最小的合数开始计算到所能达到的最大合数。 这一部分显然是属于 \([p_j^2,n]\) 。 那么考虑这一部分的贡献。 可以容易的得到转移方程。 \[g(n,j)=g(n,j-1

ZJNU 2354 - 进贡

前提是你 提交于 2020-01-28 21:50:20
分开考虑k=1 k=2和k>=3的情况 2和3这两个质数比较特殊,遇到的话直接输出1就行 对于“神灵的不满意度为m的约数中,比m小且最大的那个”这句描述,指m除了自身和1这两个因子里找最大的那个 可以从2找到sqrt(m),根据因子总是成对出现(除了sqrt(m)),所以找到一个最小因子i就可以把m/i作为最大因子 如果是质数,输出1 输入n和k k=1时,只能一次性全部进贡,直接走上述过程 k=2时,如果这个数是偶数,可以根据“偶数总能拆成两个质数之和”输出2(2和3已经特殊考虑) 如果是奇数,判断是否是质数,是则输出1,否则去寻找比n小的最大的质数p,则n可以分成p和n-p两部分(因为p最大,所以n-p尽可能小,其最大因子也能尽可能小) k=3时,如果这个数是偶数,可以根据“偶数总能拆成两个质数之和”输出2(同上) 但是,如果是奇数,判断是否是质数,是则输出1,否则将n拆成n-2和2两部分,因为2是质数,n-2此时是奇数,判断n-2是不是质数,是则输出2,否则可以把n分成3和n-3两部分,n-3定为偶数,根据“偶数总能拆成两个质数之和”,直接输出3 1 #include<bits/stdc++.h> 2 using namespace std; 3 int findm(int in){ 4 int i,d=sqrt(in); 5 for(i=2;i<=d;i++) 6 if

[转载]判断一个数是否为素数

我只是一个虾纸丫 提交于 2020-01-06 01:10:20
来源: https://blog.csdn.net/afei__/article/details/80638460 一、概念介绍 质数的定义 是 :在大于1的自然数中,除了1和它本身以外不再有其他因数的数。 质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。 0和1既不是质数也不是合数,最小的质数是2 二、方法介绍 1.最直观,但效率最低的写法 public static boolean isPrime(int n){ if (n <= 3) { return n > 1; } for(int i = 2; i < n; i++){ if (n % i == 0) { return false; } } return true; } 这里特殊处理了一下小于等于3的数,因为小于等于3的自然数只有2和3是质数。 然后,我们只需要从2开始,一直到小于其自身,依次判断能否被n整除即可,能够整除则不是质数,否则是质数。 2.初步优化 假如n是合数,必然存在非1的两个约数p1和p2,其中p1<=sqrt(n),p2>=sqrt(n)。由此我们可以改进上述方法优化循环次数。如下: public static boolean isPrime(int n) { if (n <= 3) { return n > 1; } int sqrt = (int

java 将一个正整数分解质因数(java50道经典编程题)

↘锁芯ラ 提交于 2019-12-27 01:33:47
题目 :将一个正整数分解质因数。例如:输入90,打印出90=2 3 3*5。 首先我们要对这个问题进行分析: 如果我们要对n分解质因数。应该先找到一个最小的质数k,而后按照下述步骤进行 1)如果这个质数恰好等于n,则说明分解质因数的过程已经结束,打印出即可; 2)但是如果n不等于k,但是n能被k整除,则应该打印出k的值,并且用n除以k的商,作为新的正整数n。重复执行第一步。 3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。 我们还必须要明白质数的概念,作为质数,0和1不是质数。 根据算术基本定理,每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积;而且如果不考虑这些质数在乘积中的顺序,那么写出来的形式是唯一的。最小的质数是2。 话不多说直接上代码: import java . util . Scanner ; //分解质因数 public class Prime_factor { //n代表需要输入的正整数 static int n , k = 2 ; public static void main ( String [ ] args ) { System . out . print ( "请输入一个大于2的正整数:" ) ; Scanner scanner = new Scanner ( System . in ) ; int n =

「学习笔记」min_25筛

依然范特西╮ 提交于 2019-12-26 03:52:37
前置姿势 魔力筛 其实不看也没关系 用途和限制 在 \(\mathrm{O}(\frac{n^{0.75}}{\log n})\) 的时间内求出一个积性函数的前缀和。 所求的函数 \(\mathbf f(x)\) 要满足以下条件: \(\mathbf f(p)\) 是一个多项式,其中 \(p\) 是质数 \(\mathbf f(p^c)\) 要能够快速计算。 算法流程 首先我们需要求出对于每一个 \(\left\lfloor \frac nd\right\rfloor\) 求出 \(\sum_{i=1}^{\left\lfloor \frac nd\right\rfloor} [i \in P] \mathbf f(i)\) ,其中 \(P\) 是质数集合。 首先筛出 \(\sqrt n\) 以内的质数,设 \(P_j\) 表示从小到大第 \(j\) 个质数。 设 \(\mathbf g(n, j)\) 表示所有最小质因子大于 \(P_j\) 的数加上质数的 \(\mathbf f(i)\) 的和。 那么 \(\mathbf g(n, |P|)\) 就是所求。 考虑 \(\mathbf g(n, j)\) 的转移,分两种情况。 \(P_j^2 > n\) 这个质数不会造成任何影响,于是 \(\mathbf g(n, j) = \mathbf g(n, j - 1)\) 。 \(P

面试官问:为什么 String 的 hashCode 选择 31 作为乘子?

混江龙づ霸主 提交于 2019-12-14 11:14:59
某天,我在写代码的时候,无意中点开了 String hashCode 方法。然后大致看了一下 hashCode 的实现,发现并不是很复杂。但是我从源码中发现了一个奇怪的数字,也就是本文的主角31。这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途。后来带着疑问和好奇心,到网上去找资料查询一下。在看完资料后,默默的感叹了一句,原来是这样啊。那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜。 选择31的原因 在详细说明 String hashCode 方法选择数字31的作为乘子的原因之前,我们先来看看 String hashCode 方法是怎样实现的,如下: public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; } 上面的代码就是 String hashCode 方法的实现,是不是很简单。实际上 hashCode 方法核心的计算逻辑只有三行,也就是代码中的 for 循环。我们可以由上面的 for 循环推导出一个计算公式,hashCode

欧拉函数

我们两清 提交于 2019-12-09 13:10:47
在数论,对正整数n,欧拉函数是少于或等于n的数中与n 互质 的数的数目。此函数以其首名研究者欧拉命名,它又称为Euler's totient function、 φ函数 、欧拉 商数 等。 例如φ(8)=4,因为1,3,5,7均和8 互质 。——————欧拉函数的定义 ---φ函数的值  通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有 质因数 ,x是不为0的整数。φ(1)=1(唯一和1 互质 的数(小于等于1)就是1本身)。 ( 注意:每种质因数只一个。比如12=2*2*3那么φ(12)=12*(1-1/2)*(1-1/3)=4 ) ---若n是质数p的k次幂, φ(n)=p^k-p^(k-1)=(p-1)p^(k-1) -1 ,因为除了p的倍数外,其他数都跟n互质。 (证明:P^k有p*p*p....*p个p,共P^k个p) 设n为正整数,以 φ(n)表示不超过n且与n 互素 的正整数的个数,称为n的欧拉函数值,这里函数φ:N→N,n→φ(n)称为欧拉函数。 ----与N互质所有数的和:sum=n*φ(n)/2;//因为所有大于2的欧拉函数值都是偶数,所以/不会丢失数据 ----欧拉函数的证明: --容斥原理: A∪B∪C = A+B+C - A∩B - B∩C - C∩A +A∩B∩C