算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)
文章目录
- acwing869. 试除法求约数
- acwing870. 约数个数
- acwing871. 约数之和
- acwing872. 最大公约数
acwing869. 试除法求约数
acwing869. 试除法求约数
试除法求一个数的所有约数:从小到大枚举,如果当前枚举的数是原数的约数,就记录下来(或者输出)。
优化:如果 d能整除n的话,那么 n/d也能整除n;比如,3能整除6,那么 6/3=2,2也能整除6.因为约数是一对一对出现的。
这里的的优化是只枚举较小的约数d,另一个可以直接n/d算出来,这样的话只需要枚举到n\sqrt{n}n即可。
试除法求一个数所有约数,时间复杂度O(n)O(\sqrt{n})O(n)
ac代码
#include<bits/stdc++.h>
using namespace std;//用vector来存所有约数
vector<int> get_divisors(int n){vector<int> res;for(int i= 1; i<= n/ i; i++){if(n %i ==0){res.push_back(i);//边界情况,i == n/i,只放一个就可以if(i != n/i) res.push_back(n/i);}}sort(res.begin(),res.end());return res;
}
int main(){int n;cin >> n;while(n--){int a;cin >> a;vector<int > res = get_divisors(a);//下面这种写法,避免行末空格,在PAT这种OJ上会卡掉!cout<<res[0];for(int i;i<res.size(); i++) cout<<" "<<res[i];cout<<endl;}}
acwing870. 约数个数
acwing870. 约数个数
分析:
约数个数基于算术基本定理
来源于:维基百科
假设N分解质因数(下面的p1,p2,...,pkp_1,p_2,...,p_kp1,p2,...,pk都是质数)的结果是:
N=p1a1×p2a2×...×pkakN={p_1}^{a_1}\times{p_2}^{a_2}\times...\times{p_k}^{a_k}N=p1a1×p2a2×...×pkak
则N的约数个数就等于(a1+1)×(a2+1)×...×(ak+1)(a_1+1)\times(a_2+1)\times...\times(a_k+1)(a1+1)×(a2+1)×...×(ak+1)
所以这道题,最后的那个数N是给定的所有数的乘积,对N进行分解因式,其实,可以对乘起来之前的每一个数分解质因数,相同的因数,次幂累加起来。
用到分解质因数的知识,请移步笔者另一篇文章:
算法刷题-数论-质数的判定、分解质因数、筛质数中分解质因数的知识点。
ac代码
#include<bits/stdc++.h>
using namespace std;const int mod =1e9 + 7;
typedef long long LL;int main(){int n;cin >> n;unordered_map<int,int> primes;//质因数的次幂while(n--){//每个数都分解质因数,并统计因数的次幂int x;cin >> x;for(int i=2; i<= x/i ;i++){while( x % i ==0 ){x/=i;primes[i] ++;}}if(x >1)primes[x] ++;}LL res =1;//约数个数:套公式(1+a1)(1+a2)...(1+ak)for(auto prime : primes) res = res*(prime.second+1) % mod;cout<<res<<endl;}
acwing871. 约数之和
acwing871. 约数之和
分析:
假设N分解质因数的结果是:
N=p1a1×p2a2×...×pkakN={p_1}^{a_1}\times{p_2}^{a_2}\times...\times{p_k}^{a_k}N=p1a1×p2a2×...×pkak
则这个数N的约数之和等于
(p10+p11+p12+...+p1a1)×(p20+p21+p22+...+p2a2)×...×(pk0+pk1+pk2+...+pkak)(p_{1}^{0}+p_{1}^{1}+p_{1}^{2}+...+p_{1}^{a_{1}})\times(p_{2}^{0}+p_{2}^{1}+p_{2}^{2}+...+p_{2}^{a_{2}})\times...\times(p_{k}^{0}+p_{k}^{1}+p_{k}^{2}+...+p_{k}^{a_{k}})(p10+p11+p12+...+p1a1)×(p20+p21+p22+...+p2a2)×...×(pk0+pk1+pk2+...+pkak)
以上称为“约数和定理”,在小学奥数中有应用。
补充:已知pap^apa的底数p,指数a,如何快速求出p0+p1+...+pap^0+ p^1+...+p^ap0+p1+...+pa?
有以下代码
//求(p^0+ p^1+...+p^a)的代码
int t =1;
while(a--) t = t* p +1;
ac代码
#include<bits/stdc++.h>
using namespace std;const int mod =1e9 + 7;
typedef long long LL;int main(){int n;cin >> n;unordered_map<int,int> primes;//质因数的次幂while(n--){//每个数都分解质因数,并统计因数的次幂int x;cin >> x;for(int i=2; i<= x/i ;i++){while( x % i ==0 ){x/=i;primes[i] ++;}}if(x >1)primes[x] ++;}LL res =1;for(auto prime : primes){int p = prime.first , a = prime.second; //分别是底数和指数LL t =1;//对每个质因子,求(p^0+ p^1+...+p^k)while(a--) t = (t * p +1) %mod;res = res * t % mod;}cout<<res<<endl;}
acwing872. 最大公约数
acwing872. 最大公约数
辗转相除法的核心:
(a,b)的最大公约数 =(b,a mod b)的最大公约数
amodb=a−⌊ab⌋b=a−kb,k为常数a\ mod \ b = a-\lfloor \frac{a}{b}\rfloor b =a - kb,k为常数a mod b=a−⌊ba⌋b=a−kb,k为常数
怎么证明呢?思想是证明(a,b)的公约数 和(b, a mod b)的公约数完全相同,则它们的最大公约数也相同。等价表述是,任何1个(a,b)的公约数,都是(b,a mod b)的公约数;反过来,任何1个(b,a mod b)的公约数,都是(a,b)的公约数,那么(a,b)的公约数 和(b, a mod b)的公约数完全相同。
具体证明过程略,提示:会用到数论里面的结论,若d能整除a,d能整除b,则d整除k1a+k2b,k1,k2k_1a+k_2b,k_1,k_2k1a+k2b,k1,k2是常数。
辗转相除法模板解释:
int gcd(int a, int b){//如果b !=0 则返回 gcd(b, a mod b)//如果 b==0,则返回 a ,因为0和a的最大公约数areturn b ? gcd(b, a %b) :a;
}
AC代码
#include<bits/stdc++.h>
using namespace std;int gcd(int a, int b){return b ? gcd(b, a %b) :a;
}
int main(){int n;cin >> n;while(n--){int a, b;scanf("%d%d",&a,&b);printf("%d\n",gcd(a,b));}}
算法刷题-数论-试除法求约数、约数个数、约数之和、最大公约数(辗转相除法)相关推荐
- 算法刷题-数论-质数的判定、分解质因数、筛质数
文章目录 数论 1. 质数 质数的判定---试除法 分解质因数---试除法 筛质数 朴素筛法 埃氏筛法 线性筛法 数论 1. 质数 质数:在大于1的整数中,如果只包含1和它本身这两个约数,那么这个数就 ...
- 算法刷题-数论-组合数、快速幂、逆元、递推求组合数、逆元求组合数
文章目录 acwing885. 求组合数 I(递推:数据范围:2000) acwing875. 快速幂(a的k次方 模 b) acwing876. 快速幂求逆元 acwing886. 求组合数 II( ...
- 数论 - 约数基础 【 试除法求所有约数 + 约数个数和约数之和 + 欧几里得算法-求解最大公约数 】
数论-约数基础 1.约数定义 约数,又称因数.整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a.a称为b的倍数,b称为a的约数.在大学之前,"约数 ...
- 数学知识 试除法求约数
试除法求约数 给定 n 个正整数 ai,对于每个整数 ai,请你按照从小到大的顺序输出它的所有约数. 输入格式 第一行包含整数 n. 接下来 n 行,每行包含一个整数 ai. 输出格式 输出共 n 行 ...
- 2020-07算法刷题集
2020-07算法刷题集 前言 0715-一年中的第几天 0716-分数加减运算 0717-移动石子直到连续 0719-拼写单词 0720-有效的回旋镖 0722-最后一块石头的重量 0723-有效三 ...
- 神了,无意中发现一位1500道的2021LeetCode算法刷题pdf笔记
昨晚逛GitHub,无意中看到一位大佬的算法刷题笔记,感觉发现了宝藏!有些小伙伴可能已经发现了,但咱这里还是忍不住安利一波,怕有些小伙伴没有看到. 关于算法刷题的困惑和疑问也经常听朋友们提及.这份笔记 ...
- 试除法求最小N个素数之二
Trial division 试除法求最小N个素数是一个经典的算法. 这个算法不同于前一个版本<试除法求最小N个素数>的方法,也是一个比较快速的方法. 这个算法考虑以下两点: 1.偶数中只 ...
- 找到所有数组中消失的数字_【一点资讯】千万程序员的呼声:面试如何拿到大厂Offer?这份阅读量超过11W+的算法刷题宝典请你原地查收 www.yidianzixun.com...
如何才能通过面试拿到大厂Offer? "刷leetcode!" 这是我听到最多的回答! 现在越来越多的人应聘工作时都得先刷个几十百来道题,不刷题感觉都过不了面试. 无论是面测试.算 ...
- 搬砖试金石!github星标7W算法刷题宝典,还愁拿不下大厂offer?
前言 这几年IT技术蓬勃发展,日新月异,对技术人才的需求日益增长,程序员招聘市场也如火如荼.在有限的三五轮面试中,国外流行让面试者编程解决某些数据结构和算法的题目,通过观察面试者编码的熟练程度.思考的 ...
最新文章
- boost::sort模块实现整数排序测试
- 微服务中为什么需要服务发现?
- 基于微软Synchronization Services双向同步技术在企业项目中的架构应用研究
- 浅谈电商网站开发中用户会话管理机制的设计和实现原理
- 认识Linux下的各种系统服务
- 通过反射获得私有构造器,创建对象
- linux5.5 里dns,RedHat 5.5搭建各种DNS服务器(3)
- 使用Python和Prometheus跟踪天气
- 2019级软件1班安卓实训总结
- JavaScript内建对象 (一) ----- Array
- markdown快速创建表格及内容工具
- 网易的企业免费邮箱和腾讯的企业邮箱
- c语言中term,CTerm
- 算法11 抓住波粒二象性的火星人
- 串口通信简介——发展历史与基本概念
- 2021年育婴员(五级)考试试卷及育婴员(五级)考试技巧
- 进化优化算法--第二章:爬山法
- 浅析瞬态抑制二极管双向tvs管
- linux ln命令详解
- C1认证:修改《植物大战僵尸》的文件以及code.org绘图以及bmp画图
热门文章
- 支持常见数据库差异对照说明
- 单片机直接驱动段式液晶
- 清华镜像源地址_PyCharm安装第三方库(内含添加国内镜像源方法)
- 开发转运维有什么好点的理由_企业微信SCRM哪家好点?
- 神经网络粒子和物理粒子的一个本质差别
- Java语言程序设计实验指导_《java语言程序设计》上机实验指导手册(4).doc
- linux驱动程序是什么,简述一个Linux驱动程序的主要流程与功能
- mysql悲观锁只用于读取吗_MySQL中悲观锁和乐观锁到底是什么?
- mysql 安全扫描_MySQL 安全和监控 - Can't Wait Any Longer - OSCHINA - 中文开源技术交流社区...
- 1.11 超过人的表现-深度学习第三课《结构化机器学习项目》-Stanford吴恩达教授