【算法】数论基础——唯一分解定理(算术基本定理)python

目录

  • 定义
  • 进入正题
  • 热身训练
  • 实战演练
  • 扩展衍生
  • 判断一个数是否为完全平方数
  • 举一反三
  • 总结


定义


唯一分解定理:也叫做算数基本定理:
任意一个大于1的整数N,都可以唯一分解为若干个质数的乘积

换句话说,任何大于1的整数n可以表示为:

在这里插入图片描述


例如:
30 = 2^1 * 3^1 * 5^1
100 = 2^2 * 5^2


进入正题


那么怎么去实现呢?很简单

示例实现

def prime_factor(n):
    factor = []
    for i in range(2, n + 1):
        while n % i == 0:
            n //= i
            factor.append(i)
        if n == 1:
            break
    return factor


print(prime_factor(100))
# [2, 2, 5, 5]


热身训练


分解质因数 https://www.lanqiao.cn/problems/1559/learning/?page=1&first_category_id=1&problem_id=1559

在这里插入图片描述


仅仅需要注意一下输出的格式即可


题解code:

def prime_factor(n):
    factor = []
    for i in range(2, n + 1):
        while n % i == 0:
            n //= i
            factor.append(i)
        if n == 1:
            break
    return factor


a, b = map(int, input().split())
for i in range(a, b + 1):
    print(i, end='=')
    print(*prime_factor(i), sep='*')



实战演练


k的倍数 https://www.lanqiao.cn/problems/4278/learning/?page=1&first_category_id=1&tag_relation=intersection&problem_id=4278

在这里插入图片描述
在这里插入图片描述


题解code:

def prime_factor(n):
    factor = []
    for i in range(2, n + 1):
        while n % i == 0:
            n //= i
            factor.append(i)
        if n == 1:
            break
    return factor


t = int(input())
for _ in range(t):
    n, k = map(int, input().split())
    a = list(map(int, input().split()))
    ans = []
    for i in a:
        ans += prime_factor(i)
    res = 1
    for i in range(len(ans)):
        res *= ans[i]
        if res % k == 0:
            print('Yes')
            break
    else:
        print('No')

扩展衍生


如果一个数 n 是完全平方数,则其每个质因子的次数必定为偶数。

给出证明:

在这里插入图片描述


判断一个数是否为完全平方数


基于上述性质,判断一个数是否为完全平方数:
1.对该数进行质因数分解。
2.检查每个质因数的指数是否都是偶数。
3.如果所有质因数的指数都是偶数,则该数是完全平方数;否则,不是完全平方数。


示例实现code:

from collections import defaultdict

# 唯一分解定理
def prime_factors(n):
    factors = []
    for i in range(2, n + 1):
        while n % i == 0:
            factors.append(i)
            n //= i
        if n == 1:
            break
    return factors

# 如果有质因数的指数为奇数,则返回0
def is_square(n):
    cnt = defaultdict(int)
    factors = prime_factors(n)
    for i in factors:
        cnt[i] += 1
    for i in cnt.values():
        if i % 2 == 1:
            return 0
    return 1


n = int(input())
print(is_square(n))


举一反三


第十二届蓝桥杯省赛C++ A/B组真题 完全平方数 https://www.acwing.com/problem/content/description/3494/


题目描述:

一个整数 a a a 是一个完全平方数,是指它是某一个整数的平方,即存在一个整数 b b b,使得 a = b 2 a = b^2 a=b2

给定一个正整数 n n n,请找到最小的正整数 x x x,使得它们的乘积是一个完全平方数。

输入格式

输入一行包含一个正整数 n n n

输出格式

输出找到的最小的正整数 x x x

数据范围

对于 30 30\\% 30 的评测用例, 1 ≤ n ≤ 1000 1 ≤ n ≤ 1000 1n1000,答案不超过 1000 1000 1000
对于 60 60\\% 60 的评测用例, 1 ≤ n ≤ 1 0 8 1 ≤ n ≤ 10^8 1n108,答案不超过 1 0 8 10^8 108
对于所有评测用例, 1 ≤ n ≤ 1 0 12 1 ≤ n ≤ 10^{12} 1n1012,答案不超过 1 0 12 10^{12} 1012

输入样例1:

12

输出样例1:

3

输入样例2:

15

输出样例2:

15

思路分析:

完全平方数其质因子次数一定为偶数,
如果其质因子次数为奇数,我们就将ans * 此质因子


实现:

from collections import defaultdict


def prime_factors(n):
    factors = []
    for i in range(2, n + 1):
        while n % i == 0:
            factors.append(i)
            n //= i
        if n == 1:
            break
    return factors


n = int(input())
res = prime_factors(n)
ans = 1
cnt = defaultdict(int)
for i in res:
    cnt[i] += 1
for key, value in cnt.items():
    if value % 2 == 1:
        ans *= key
        if ans == n:
            break
print(ans)

结果超时(因为此题n为1e12)
现在需要想想怎么优化


发现当前的代码在质因数分解部分的时间复杂度较高
从2到n逐个检查是否为质因数,这导致时间复杂度O(n)。
对于 n≤1e12 来说效率较低。
需要改进,优化质因数分解的时间复杂度:

预处理得到质数表,只需要检查质数作为可能的因子,而不是所有整数。


题解code:

from collections import defaultdict


def Euler(n):  # 通过欧拉筛得到质数表
    is_prime = [True] * (n + 1)
    primes = []
    for i in range(2, n + 1):
        if is_prime[i]:
            primes.append(i)
        for p in primes:
            if i * p > n:
                break
            is_prime[i * p] = False
            if i % p == 0:
                break
    return primes


def prime_factors(n):
    factors = []
    for prime in prime_list:
    	# 在质因数分解时只遍历到sqrt(n)
        if prime * prime > n:   
            break
        while n % prime == 0:
            factors.append(prime)
            n //= prime
    # 如果剩下的n是一个大于sqrt(n)的质数,也应加入factors中
    if n > 1:  
        factors.append(n)
    return factors


prime_list = Euler(int(1e7))
n = int(input())
res = prime_factors(n)
ans = 1
cnt = defaultdict(int)
for i in res:
    cnt[i] += 1
for key, value in cnt.items():
    if value % 2 == 1:
        ans *= key
        if ans == n:
            break
print(ans)

不会预处理质数表的小伙伴可以点此进入详细讲解

素数筛法:埃氏筛与欧拉筛


总结


通过理解和应用唯一分解定理,我们可以更好地分析和解决与整数相关的复杂问题。


如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/959669.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

互联网医院成品|互联网医院开发|互联网医院搭建

在数字化医疗蓬勃发展的当下,互联网医院系统已成为医疗服务体系中至关重要的组成部分。它打破了传统医疗服务在时间和空间上的限制,为患者提供了更加便捷、高效的医疗服务。而一套完善的互联网医院系统,有几个功能是不能缺少的。 在线问诊功能…

Go的内存逃逸

Go的内存逃逸 内存逃逸是 Go 语言中一个重要的概念,指的是本应分配在栈上的变量被分配到了堆上。栈上的变量在函数结束后会自动回收,而堆上的变量需要通过垃圾回收(GC)来管理,因此内存逃逸会增加 GC 的压力&#xff0…

填充每个节点的下一个右侧节点指针力扣--116,117

目录 题目 思路 代码 题目 116 给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下: struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针&#xff0c…

钉钉群机器人设置——python版本

钉钉群机器人设置——python版本 应用场景钉钉界面操作程序开发效果展示 应用场景 由于工作需要,很多项目执行程序后出现报错信息无法第一时间收到,因此实时预警对于监控程序还是有必要。(仅个人观点) 参考文档及博客&#xff1a…

初步认识操作系统(Operator System)

目录 一、概念二、设计OS的目的三、定位四、操作系统上下的分级五、如何理解 "管理"六、总结 一、概念 任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)。操作系统包括: 内核(进程管理,内存管理&#xff0c…

文明6mod发布并开源:更多的蛮族营地扫荡收益mod

更多的蛮族营地扫荡收益mod(More_Barbarian_Camp_RAID_luke) 效果为: 更多的蛮族营地扫荡收益,增加到100金币,适用于野蛮氏族模式 原版本的扫荡收益非常鸡肋~! mod下载链接: https://downlo…

社区养老服务平台的设计与实现(代码+数据库+LW)

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱,出错率高,信息安全性差&#…

websocket实现

由于安卓资源管理器展示的路径不尽相同,各种软件保存文件的位置也不一定一样.对于普通用户上传文件时,查找文件可能是一个麻烦的事情.后来想到了一个办法,使用pc端进行辅助上传. 文章目录 实现思路1.0 实现定义web与客户端通信数据类型和数据格式web端websocket实现web端对客户…

(一)HTTP协议 :请求与响应

前言 爬虫需要基础知识,HTTP协议只是个开始,除此之外还有很多,我们慢慢来记录。 今天的HTTP协议,会有助于我们更好的了解网络。 一、什么是HTTP协议 (1)定义 HTTP(超文本传输协议&#xff…

arcgis短整型变为长整型的处理方式

1.用QGIS的重构字段工具进行修改,亲测比arcgis的更改字段工具有用 2.更换低版本的arcgis10.2.2,亲测10.5和10.6都有这个毛病,虽然官方文档里面说的是10.6.1及以上 Arcgis10.2.2百度链接:https://pan.baidu.com/s/1HYTwgnBJsBug…

从音频到 PDF:AI 全流程打造完美英文绘本教案

今天把英文绘本的自学教案自动生成流程完成了,我分享一下整个实现思路,让你也轻松搞定英文绘本教案的产出,让孩子的学习之路更加顺畅。  从音频到 PDF:AI 全流程打造完美英文绘本教案 一、音频转文本:AI 助力第一步 …

C++ Qt练习项目 日期时间数据

个人学习笔记 代码仓库 GitCode - 全球开发者的开源社区,开源代码托管平台 新建项目 设计UI 实现组件功能 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }…

HarmonyOS DevEco Studio模拟器点击运行没有反应的解决方法

HarmonyOS DevEco Studio模拟器点击运行没有反应的解决方法 翻遍了CSDN,试了所有办法都没办法,最后偶然间竟然解决了 解决方法其实很简单:本地模拟器下载路径下面不能有中文。。。。。 切换正确路径以后,成功运行,哦…

开发环境搭建-1:配置 WSL (类 centos 的 oracle linux 官方镜像)

一些 Linux 基本概念 个人理解,并且为了便于理解,可能会存在一些问题,如果有根本上的错误希望大家及时指出 发行版 WSL 的系统是基于特定发行版的特定版本的 Linux 发行版 有固定组织维护的、开箱就能用的 Linux 发行版由固定的团队、社…

dm8在Linux环境安装精简步骤说明(2024年12月更新版dm8)

dm8在Linux环境安装详细步骤 - - 2025年1月之后dm8 环境介绍1 修改操作系统资源限制2 操作系统创建用户3 操作系统配置4 数据库安装5 初始化数据库6 实例参数优化7 登录数据库配置归档与备份8 配置审计9 创建用户10 屏蔽关键字与数据库兼容模式11 jdbc连接串配置12 更多达梦数据…

一文讲解Java中的重载、重写及里氏替换原则

提到重载和重写,Java小白应该都不陌生,接下来就通过这篇文章来一起回顾复习下吧! 重载和重写有什么区别呢? 如果一个类有多个名字相同但参数不同的方法,我们通常称这些方法为方法重载Overload。如果方法的功能是一样…

chrome插件:网站视频下载

前置条件: 安装有chrome谷歌浏览器的电脑 使用步骤: 1.打开chrome扩展插件 2.点击管理扩展程序 3.加载已解压的扩展程序 4.选择对应文件夹 5.成功后会出现一个扩展小程序 6.点击对应小程序 7.输入对应网站,点击插件视频下载助手

【ComfyUI专栏】ComfyUI 部署Kolors

什么是Kolors?我相信一定会有朋友可能第一次听说这个生图的模型,开始我也很难想象,这竟然是快手推出的可灵AI的项目,我们可以直接利用模型来生成图片和视频。 大家可以通过直接访问可灵AI的网址获取到可灵的项目,但是对于我们来说我们需要基于ComfyUI来生成必要的图片和视…

Python Typing: 实战应用指南

文章目录 1. 什么是 Python Typing?2. 实战案例:构建一个用户管理系统2.1 项目描述2.2 代码实现 3. 类型检查工具:MyPy4. 常见的 typing 用法5. 总结 在 Python 中,静态类型检查越来越受到开发者的重视。typing 模块提供了一种方式…

250125-package

1. 定义 包就是文件夹,作用是在大型项目中,避免不同人的编写的java文件出现同名进而导致报错;想象一个场景,在一个根目录中,每一个人都有自己的一个java文件夹,他可以将自己编写的文件放在该文件夹里&…