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

【算法】约数个数、约数和

目录

【求⼀个整数的所有约数】

【求 [1, n] 每个数的约数集合】

【约数个数定理】

【求单个数的约数个数】

【约数和定理】

【求单个数的约数之和】


【求⼀个整数的所有约数】

对于⼀个整数 ,若 d 是 x 的约数,那么 x/d 也是 x 的约数。也就是说,除了完全平⽅数,约数
都是成对出现的。因此,可以⽤试除法求⼀个整数的所有约数。枚举 [1,根号n] 之间的整数,判断是否能整除。试除法也能求出⼀个整数的约数个数以及约数总和。

int d[N], cnt; // d 数组:记录所有约数,cnt:约数个数 void get_d(int x) { // 注意从 1 开始循环,1 可以是约数 for (int i = 1; i <= x / i; i++) { if (x % i == 0) // 如果 i 可以整除 x,说明 i 是 x 的约数 { d[cnt++] = i; if (i != x / i) d[cnt++] = x / i; } } }

枚举到 根号n ,因此时间复杂度为 O( 根号N) 。由于约数通常成对出现,假设某个数,从 1

到 根号n 都是它的约数,那么⼀个整数 n 的约数个数的上限为 2*根号n

【求 [1, n] 每个数的约数集合】

如果⽤试除法分别求每⼀个数的约数,时间复杂度过⾼(O(n*根号n)。可以反过来想,对于每个数 d, [1, n] 中以 d 为约数的数就是 d 的倍数。因此可以⽤倍数法求出 [1, n] 每个数的约数集合。枚举 [1, n] 中的数 ( i ) 的所有倍数(i*j),看看该倍数(i*j)是否 <= n,如果是,就在(i*j)这个数的约数集合中添加 i。

int n; vector<int> d[N]; // d[i] 是 i 的约数集合 void get_d() { for (int i = 1; i <= n; i++) // 枚举所有约数 for (int j = 1; j <= n / i; j++) // 约数的倍数 d[i * j].push_back(i); }

【约数个数定理】

【求单个数的约数个数】

• 第⼀种⽅式:枚举 1 到 根号n 之间的整数;

int cnt; // cnt:约数个数 void get_d(int x) { // 注意从 1 开始循环,1 可以是约数 for (int i = 1; i <= x / i; i++) { if (x % i == 0) // 如果 i 可以整除 x,说明 i 是 x 的约数 { cnt++ if (i != x / i) cnt++; } } }

• 第⼆种⽅式:在分解质因数的过程中,利⽤公式可以直接计算出某个数的约数个数

int c[N]; // c[i] 表⽰ i 这个质数出现的次数 // 比如 600 :c[2] == 3、c[3] == 1、c[5] == 2 int ret; //约数个数 void sum_of_prime(int x) { for (int i = 2; i <= x / i; i++) // 注意防溢出 { int cnt = 0; while (x % i == 0) // 只要有这个因⼦,就除尽,并且计数 { x /= i; cnt++; } c[i] += cnt; } if (x > 1) c[x]++; // 不要忘记判断最后⼀个质数 // 公式可以直接计算出某个数的约数个数 for(int i = 2; i <= n; i++) if(c[i]) ret *= (c[i] + 1); }

【约数和定理】

【求单个数的约数之和】

• 第⼀种⽅式:枚举1 到根号 n 之间的整数;

int sum; // sum:约数和 void get_d(int x) { // 注意从 1 开始循环,1 可以是约数 for (int i = 1; i <= x / i; i++) { if (x % i == 0) // 如果 i 可以整除 x,说明 i 是 x 的约数 { sum += i; if (i != x / i) sum += x / i; } } }

• 第⼆种⽅式:在分解质因数的过程中,利⽤公式可以直接计算出某个数的约数总和。

int c[N]; // c[i] 表⽰ i 这个质数出现的次数 // 比如 600 :c[2] == 3、c[3] == 1、c[5] == 2 int ret; //约数和 void sum_of_prime(int x) { for (int i = 2; i <= x / i; i++) // 注意防溢出 { int cnt = 0; while (x % i == 0) // 只要有这个因⼦,就除尽,并且计数 { x /= i; cnt++; } c[i] += cnt; } if (x > 1) c[x]++; // 不要忘记判断最后⼀个质数 // 公式可以直接计算出某个数的约数和 for(int i = 2; i <= n; i++) { if(c[i]) { int tmp = 1; for(int j = 1; j <= c[i]; j++) { tmp += pow(i,j); } ret *= tmp; } }
http://www.jsqmd.com/news/457759/

相关文章:

  • 【保姆级教程】Windows系统下使用国内阿里云大模型接入Claude Code
  • python中交互式和文件式的运行
  • P2并联混动仿真模型:探索未来汽车的动力与经济性
  • [HC04-Arduino]——光电探测器
  • 消息队列(MQ)入门必知必会五大基础概念:异步,削峰,解耦,生产者,消费者详细解读 一篇搞懂 超强类比
  • 11b. OpenAI API密钥获取指南
  • Serverless冷启动性能优化:从Firecracker微虚拟机隔离到代码预热算法的深度实践
  • 如何告别炉石传说“盲打“困境?HSTracker带来的智能对战革命
  • (五)RT-Thread设备驱动实战--IO模型PIN与UART
  • BTC脚本
  • 3步打造你的专属游戏助手:献给LOL玩家的效率提升方案
  • 周红伟:首家独发,腾讯龙虾WorkBuddy股票预测实操,OpenClaw实 - 今日头条
  • 2026冲孔机市场风向标:这些品牌CNC技术领先,PSH-JSM伺服折弯机/光纤激光切割机,冲孔机品牌有哪些 - 品牌推荐师
  • 字母异位词分组
  • 5个方法让Zotero成为LaTeX文献管理的理想工具
  • 超简单!百度贴吧一键自动签到(附Python完整脚本下载 )Windows 教程 养号用!
  • 2026职业小说作者生存指南:新人写小说签约难?AI辅助流工作法+5款主流的工具测评
  • 直播内容管理的自动化革命:如何用douyin-downloader实现高效内容保存
  • 3种高效管理Windows Defender的系统优化方案
  • OpenClaw 3.7 最重磅更新:ContextEngine 插件接口源码级拆解 —— AI Agent 上下文管理从此告别硬编码
  • 改进感受野模块的YOLOv5在无人机视角下微小车辆检测
  • golang的fs除了定权限还能干什么?
  • 复试准备day8
  • 解锁系统级操作:5大场景掌握权限管理精髓
  • 如何真正掌控微信数据?WeChatMsg的非典型应用指南
  • 计算机毕业设计java基于Vue.js的工资管理系统的设计与实现 基于SpringBoot的智慧游乐园综合运营管理平台设计 游乐园项目预约与排队叫号一体化管理系统的研发
  • Ansible解锁便捷运维新方式,内网 NAS 也能远程管
  • AI大模型数据治理架构搭建(非常详细):从顶层设计到落地实践,从入门到精通,收藏这一篇就够了!
  • 从此告别拖延,AI论文平台 千笔ai写作 VS 笔捷Ai,本科生专属利器!
  • 汇编代码注入器源码