当前位置: 首页 > news >正文

Python版本的常见模板(二) 数论(一)

文章目录

  • 前言
  • 质数相关
    • 质数判断
    • 求约数
    • 求取区间质数
      • 埃氏筛法
      • 线性筛法
    • 分解质因数
  • 欧拉
    • 欧拉函数
      • 求取单个数
      • 线性筛法求取
    • 欧拉定理
    • 求逆元
      • 快速幂/幂取模
  • 欧几里得算法
    • 求最小公约数
    • 拓展欧几里得算法
    • 求解同余方程

前言

本文主要是提供Python版本的常见的一些与数论相关的模板,例如求解质数,质因数分解,简单博弈论,以及组合型问题(经典的括号匹配组合问题)等等。至于原理与证明的话,由于存在大量的数学公式推理,因此本文不展示,仅展示代码与变量说明和使用场景。

注意: 相关原理将使用红色字体进行标注,证明可自行查阅资料。本文不再赘述!

质数相关

质数判断

朴素方式:

def isPrim(n):if(n==1):return Falsefor i in range(2,n):if(n%i==0);return Falsereturn True

之后的话,由于除法的一些性质,当 n/d = d 的时候,d^2 = n 在这个循环过程当中 d^2 <= n 这个时候的话,是没有必要全部除去的,只需要一般就好了。

优化版本:

def isPrime(n):if(n==1):return i = 2while(i<=(n//i)):if(n%i==0):return Falsereturn True

求约数

这个的话就是前面说的那句话的比较好的运用

def yueShu(n):i = 1while(i<=n//i):if(n%i==0):print(i)if(i!=n//i):print(n//i)i+=1

此外:
在这里插入图片描述

求取区间质数

现在我们知道了如何判断一个质数,那么现在我们需要求取一个区间内的质数,例如,我们需要求取,从1~n之间所有的质数有哪些?

埃氏筛法

直接看到代码:

def getPrims(n):prime = [0] * (n+1):st = [False] * (n+1)cnt = 0for i in range(2,n+1):if(not st[i]):prime[cnt] = icnt+=1j = i+iwhile(j<=n):st[j] = Truej+=i

这个的话,就是把这个质数的倍数给筛掉。

线性筛法

埃氏筛法的效率还是可以的,但是还可以优化一下。

def getPrim(n):prime = [0] * (n+1):st = [False] * (n+1)cnt = 0for i in range(2,n+1):if(not st[i]):prime[cnt] = icnt+=1j = 0while(prime[j] <=n//i):st[prime[j]*i] = Trueif(i%(prime[j])==0):breakj+=1

这个的话就是把那个筛选的给优化了一下。

分解质因数

ok,接下来是分解质因数,这个分解质因数是很有用的东西。

N = p1^a1 * p2*a2 …pk^ak
对于一个数N都可以拆解为这样的样子,其中这个P是质数

def division(n):i = 2while(i<=n/i):if(n%i==0):a = 0while(n%i==0):n//=ia+=1print("当前质因数为:{},对于的幂是{}".format(i,a))if(n>1):print("当前质因数为:{},对于的幂是{}".format(n,1))

欧拉

这个东西的话和我们的这个质数还是有点关系的。

欧拉函数

欧拉函数φ(5) 表示从1~5 当中和5 互质的元素个数有几个。

求取单个数

同样的和我们刚刚的这个质数是类似的,可以直接求取这个欧拉函数,也有求取一个区间的所有欧拉函数值。
在这里插入图片描述


def OuLa(n):res = ni = 2while(i<=(n//i)):if(n%i==0):while(n%i==0):n//=i#res = res* (1-(1/i)) 优化一下避免处于小数res = res // i *(i - 1)return res

线性筛法求取

这个的话就是求取这个1~n这个范围的所有的欧拉数

def ouLaLiner(n):prim = [0] * (n+1)st = [False] * (n+1)cnt = 0phi = [1] * (n+1) # φ(1) = 1for i in range(2,n+1):if(not st[i]):prim[cnt] = ii+=1phi[i] = phi[i-1]j = 0while(prim[j]<=n//i):st[prim[j]*i] = Trueif(i%prim[j]==0):phi[prim[j]*i] = phi[i] *(prim[j])breakphi[prim[j]*i] = phi[i] *(prim[j]-1)j+=1 

欧拉定理

那么接下来就是这个欧拉定理,这个欧拉定理的话,可以用在我们的求逆元的时候用上。

这个定理非常简单。
在这里插入图片描述

求逆元

在这里插入图片描述

那么这里的话,求解的时候的话,还需要一个求快速幂的算法

快速幂/幂取模

def KuaiSu(a,k):res = 1while(k):if(k%2==0):res*=aa*=ak//=2return res
def KuaiSu(a,k,p):res = 1while(k):if(k%2==0):res*=a % pa*=a % pk//=2return res

原理是这个:

(a + b) % p = (a % p + b % p) % p(1)

(a - b) % p = (a % p - b % p ) % p (2)

(a * b) % p = (a % p * b % p) % p .(3)

欧几里得算法

求最小公约数

这里的话主要是这个欧几里得算法,这个欧几里得算法的话作用还是非常大的,一个是求取最小公约数,然后的话就是用拓展欧几里得算法来求取这个同余方程(当然这块是先用裴蜀定理可以证明一下)

def gcd(a,b):if(b==0):return areturn (b,a%b)

拓展欧几里得算法

在这里插入图片描述
我们使用这个拓展欧几里得算法的话可以求出这个来。
我们先来直接看到代码:

globe x=0,y=0
def exgcd(a,b,x,y):if(b == 0):x = 1,y = 0return ad = exgcd(b, a % b, y, x);y -= (a//b) * x;return d

这里的话这个y 是这样的:
在这里插入图片描述

求解同余方程

那么这个拓展欧几里得算法的话就可以去求解同余方程以及我们刚刚的求逆元。

因为我们那个求逆元其实也就是解一个同余方程,只是那个方程比较特殊而已。

为什么可以怎么来的如下:
在这里插入图片描述
这里的话就不给代码了,上面有。然后求逆的话是这样的:
在这里插入图片描述

http://www.lryc.cn/news/10223.html

相关文章:

  • SQL快速上手(知识点总结+训练资料)
  • 无需经验的steam搬砖,每天操作1小时,轻松创业赚钱!
  • 如何创建你的公司的FAQ页面?
  • CK-GW06-E03与欧姆龙PLC配置指南
  • 使用docker-compose部署RocketMQ5.0
  • 嵌入式ARM设计编程(四) ARM启动过程控制
  • 企业维基都说好,今天我们来看看 wiki 软件的缺点有哪些?
  • 08- 汽车产品聚类分析综合项目 (机器学习聚类算法) (项目八)
  • 揭开苹果供应链,如何将其命运与中国深度捆绑
  • Mybatis 之useGeneratedKeys注意点
  • 数据结构---时间复杂度
  • 如何保证集合是线程安全的 ConcurrentHashMap如何实现高效地线程安全?
  • C++对象模型和this指针
  • kubernetes教程 --Pod调度
  • 功率放大器科普知识(晶体管功率放大器的注意事项)
  • CentOS 7转化系统为阿里龙蜥Anolis OS 7
  • 【快速复习】一文看懂 Mysql 核心存储 隔离级别 锁 MVCC 机制
  • 面试题----集合
  • XSS注入基础入门篇
  • 刷题 - 数据结构(二)链表
  • 用于隔离PWM的光耦合器选择和使用
  • 面试完阿里,字节,腾讯的测试岗,复盘以及面试总结
  • 分享一个外贸客户案例
  • 【Kubernetes】第二篇 - 购买阿里云 ECS 实例
  • 数影周报:据传国内45亿条快递数据泄露,聆心智能完成Pre-A轮融资
  • Leetcode力扣秋招刷题路-0073
  • 遥感数字图像处理
  • 深度学习常用的python函数(一)
  • 2023年美国大学生数学建模A题:受干旱影响的植物群落建模详解+模型代码(一)
  • PPS文件如何转换成PPT?附两种方法