C++课程总结——数论

质数:

  • 质数:一个正整数不能被除了1和它本身的任何一个自然数整除的数称为质数(prime)

求质数

试除:

  • 根据质数的定义,我们可以发现:若 ( 1 < k < n ) ( 1< k<n) (1<k<n)都不能能整除 n n n,则 n n n为质数,进一步思考:如果 k ∣ n k\mid n kn则定会有一个 k 1 × k = n k_1\times k=n k1×k=n k 1 ≤ n k_1\leq \sqrt n k1n .
  • 所以对于任意正整数,只需要枚举2~ n \sqrt n n 的所有数判断是否为 n n n的约数就能判断 n n n是否为质数.

筛法:

  • 当我们求1~n的所有质数时上述方法的时间复杂度就为 O ( n × n ) O(n\times \sqrt n ) O(n×n ).
  • 但使用埃氏筛,线性筛可以将复杂度优化到 O ( n × log ⁡ log ⁡ n ) O(n\times \log\log n) O(n×loglogn) O ( n ) O(n) O(n)
埃氏筛
  • 1.能被两个或多个数相乘得到的数一定不是质数.
  • 2.任何一个合数都能被若干个质数相乘得到.(算数唯一分解定理)

反证法:
假设存在一个合数n不是由若干个质数相乘得出,n存在一个最小的合数m,
因为m为合数,则定有 a × b = m a\times b=m a×b=m
若a,b均为质数,则与假设相矛盾,假设不成立,
若a,b中有一个为质数,则会存在一个更小的合数 m 1 , m_1, m1,与假设相矛盾,假设不成立

  • 3.假设x为一个质数,则小于 x 2 x^2 x2的合数会被小于x的另一个质数y所更新(x会乘到y,同理y会乘到x)
  • 根据以上三点,我们可以得到埃拉托斯特尼筛法,简称埃氏筛
	for(int i = 2; i <= n; i ++){
   //注意这个从2开始,1特殊处理(筛2~n的质数)
		if( t[i] == 0 ) prime[ ++tot ] = i;//0代表从未被标记,即i是质数
		for(int j = i * i; j <= n; j += i){
   //从i^2开始(上述第3条)
			t[j] = 1;//标记程到的合数
		}
	} 

线性筛

1.与埃氏筛原理一样,用质数标记合数
2.不同点:

线性筛确认了更新一个合数的唯一方式,即用这个数的最小质数去标记,所以线性筛的时间复杂度为 O ( n ) O(n) O(n)

3.实现方法:

	for(int i = 2; i <= n; i ++){
   
		if(t[i] == 0){
   
			t[i] = i;//更新一个质数的最小质数当然是它本身
			ptime[++tot] = i;
		}
		for(int i = 1; i <= tot; i ++){
   //枚举每一个已标记的质数,去更新
			if(prime[i] > t[i] || prime[j] > n / i) break;//线性筛的核心
			//如果prime[i]>t[i],则不满足对i*prime[j]的最小更新,自己举个例子(感性理解一下)
			t[i * prime[i]]
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值