GCD,乘法逆元
最大公约数
公约数:几个整数共有的约数。($ \pm 1是任何整数的公约数$)
最大公约数:显而易见,所有公约数中最大的那个。
欧几里得算法
为了求最大公约数(常记为GCD),我们常用欧几里得算法。以两个数的最大公约数为例。设正整数a,b。不妨假设\(a>b\)。
\]
证明
当 \(b\mid a\)时,很明显,\(gcd(a,b)=b\)。
当 \(b\nmid a\)时,设\(a=k\times b+r,d=gcd(a,b)\)。那么 \(r=a\ mod\ b,\ d\mid a且d\mid b\),等式同除\(d\),得到 \(\frac{a}{d}=k\times \frac{b}{d}+\frac{r}{d}\),等式左侧为整数,则 \(\frac{r}{d}\) 也为整数。
Code
由此我们得到一个递归的写法
int gcd(int a,int b)
{
if(b==0)return a;
else return gcd(b,a%b);
}
令n为a,b之中的较大数,时间复杂度 \(O(log\ n)\)。
更相减损术
由于大整数取模速度很慢,我们用加减法代替取模运算可以证明 $ \forall d \mid a,d \mid b,有d \mid a-b $,因此
\]
怎么求多个数的最大公约数?我们可以每次求其中两个整数的gcd,并将其放回原数列,继续求解,不会对结果有影响。
最小公倍数 \((LCM)\)
利用最大公约数求LCM
已知整数\(a,b\),进行质因数分解
\(a=p_{a_1}^{k_{a_1}} \times p_{a_2}^{k_{a_2}} \times \ldots \times p_{a_n}^{k_{a_n}} ,b=p_{b_1}^{k_{b_1}} \times p_{b_2}^{k_{b_2}} \times \ldots \times p_{b_m}^{k_{b_m}}\)
易知 $ gcd(a,b)=p_1^{min(k_{a_1},k_{b_1})} \times p_2^{min(k_{a_2},k_{b_2})} \times \ldots \times p_n^{min(k_{a_n},k_{b_n})} $ , $ lcm(a,b)=p_1^{max(k_{a_1},k_{b_1})} \times p_2^{max(k_{a_2},k_{b_2})} \times \ldots \times p_n^{max(k_{a_n},k_{b_n})} $
$\because min(k_{a_i},k_{b_i}) \times max(k_{a_i},k_{b_i})=k_{a_i} \times k_{b_i} $
$\therefore gcd(a,b) \times lcm(a,b)=a \times b $
扩展欧几里得算法
用于求解关于 \(x,y\) 形如 $ax+by=gcd(a,b) $的方程的一组可行的整数解。
证明
当 $ gcd(a,b)=a $时,显然有一组解 $ x=1,y=0 $
对于一般情况,设 $ ax_1+by_1=gcd(a,b) $
$ bx_2+(a \mod b)y=gcd(b,a\mod b) $
由欧几里得可知,$ gcd(a,b)=gcd(b,a\mod b) $
$ ax_1+by_1=bx_2+(a\mod b)y_2 $
又因为 $ a\mod b=a-b\times \left \lfloor \frac{a}{b} \right \rfloor $ ,整理可得
\]
由于我们只要得到一组解即可,令 $ x_1=y_2,\ y_1=x_2-\left \lfloor \frac{a}{b} \right \rfloor y_2 $
Code
int exgcd(int a,int b,int &x,int &y)
{
if(!b){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
例题 倒酒
思路
a mL的酒杯最后剩下的酒为b mL酒杯向 a中倒入的总酒量减a倒回酒桶的酒量,设a酒杯倒出x次,b酒杯倒入a酒杯y次,最后剩余酒的最小值为c。
得到方程 $ by-ax=c $
那么何时c取最小值?其实就是 $ gcd(a,b) $
证明
反证法,设整数 $ r<gcd(a,b)且 by-ax=r $,令 $ d=gcd(a,b) $
\]
\]
$ \because d=gcd(a,b) \ $ $ \therefore d \mid a 且 d \mid b $
$ \because r<d \ $ $ \therefore d \nmid r $
$ \because 等式左侧必为整数,等式右侧必为分数 $
$ \therefore 假设不成立 $
$ by-ax 的最小值为 gcd(a,b) $
证毕
利用 \(exgcd\) 求出一组可行的解 \(x_1,y_1\) ,注意我们求解的方程是 $ ax+by=gcd(a,b) $ , \(x\)取负数,方程就转换为 $ -ax+by=gcd(a,b) $ ,题干的要求是使 \(x\) 最小,同时保证 \(x,y\) 均为正整数,应该怎么处理?
令 $ a_1= \frac{a}{gcd(a,b)}, b_1= \frac{b}{gcd(a,b)} $
则 $ a_1x_1+b_1y_1=1 $
$ a_1 x_2+ a_1 \Delta x +b_1y_1=1 $
$ a_1x_2+b_1(y_1+ \frac{a_1 \Delta x }{b_1} )=1 $
$ \because y_2=y_1+ \frac{a_1 \Delta x}{b_1} 为正整数 $
$ \therefore b_1 \mid a_1 \Delta x $
$ \because gcd(a_1,b_1)=1 $
$ \therefore b_1 \mid \Delta x $
$ x_2=x_1- \Delta x $ 且 \(x_2\) 取最小正整数, $x_2=x_1 \mod b_1 $,因为 \(x_1\) 可能为负数 ,$ x_2=(x_1 \mod b_1+b_1 ) \mod b_1 $
Code
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b,c;
int x,y;
int exgcd(int a,int b,int &x,int &y)
{
if(!b){
x=1;
y=0;
return a;
}
int d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
signed main()
{
scanf("%lld%lld",&a,&b);
c=exgcd(a,b,x,y);
cout<<c<<endl;
x=-x;
b/=c;
a/=c;
c=1;
x=(x%b+b)%b;
y=(c+a*x)/b;
cout<<x<<' '<<y<<endl;
}
乘法逆元
定义
关于 \(a,p\)的同余方程 $ ax \equiv 1 (\mod p ) $, \(x\)称为 \(a\)在模 \(p\) 意义下的乘法逆元,其中 \(a,p\)互素 , 记作 $ x=a^{-1} $
性质
我们经常遇到这种场景,已知整数 $ a,b(很大,需要取模) $,求 \(a/b\)。
由于a,b不能直接存下,只能进行取模,令 $ x=a\mod q,y=b\mod q $ ,这样问题就来了,取模之后在做除法不能保证结果正确。这时,乘法逆元启动。
$ x \times x^{-1} \equiv 1(\mod p) $
由同余的相关性质可知, $ a\times x\times x^{-1} \equiv a(\mod p) $
又 $ ax\div x\equiv a (\mod p) $
由此,得出结论,在同余方程中,除以整数 \(x\),相当于乘 \(x\)的逆元。
同时也可以证明 \(a,p\)不互素时,\(a\)没有逆元。
求逆元
单点求逆元
我们当然可以用扩展欧几里得解同余方程求逆元,这里不再解释。
也可以用快速幂和费马小定理求逆元,但蒟蒻不会,详见OI Wiki。
线性求逆元
求出 \(1,2,\dots ,n\) 中每个数在模 \(p\) 意义下的逆元,保证互素。
当 $ n\ge 1e7 $ 时 ,\(O(n logn)\) 求逆元就不现实了,考虑线性求逆元。
显然, $ 1^{-1}=1 $
对于 \(i\ne 1\) 的情况, \(p=ki+j\), $k=\left \lfloor \frac{p}{i} \right \rfloor ,j=p \mod i $ 。
\]
\]
同乘 $i^{-1}\times j^{-1} $
\]
\]
\]
保证 $i^{-1}> 0 $, $ i^{-1}=(p-\left \lfloor \frac{p}{i}\right \rfloor)\times (p\mod i)^{-1}\mod p $
Code
#include<bits/stdc++.h>
using namespace std;
const int N=5e6;
#define int long long
int n,p;
int inv[N];
signed main()
{
cin>>n>>p;
inv[1]=1;
puts("1");
for(int i=2;i<=n;i++){
int k=p/i;
int j=p%i;
inv[i]=(long long)(p*k-inv[j]*k)%p;
printf("%lld\n",inv[i]);
}
}
GCD,乘法逆元的更多相关文章
- 【板子】gcd、exgcd、乘法逆元、快速幂、快速乘、筛素数、快速求逆元、组合数
1.gcd int gcd(int a,int b){ return b?gcd(b,a%b):a; } 2.扩展gcd )extend great common divisor ll exgcd(l ...
- 【learning】 扩展欧几里得算法(扩展gcd)和乘法逆元
有这样的问题: 给你两个整数数$(a,b)$,问你整数$x$和$y$分别取多少时,有$ax+by=gcd(x,y)$,其中$gcd(x,y)$表示$x$和$y$的最大公约数. 数据范围$a,b≤10^ ...
- 数论入门2——gcd,lcm,exGCD,欧拉定理,乘法逆元,(ex)CRT,(ex)BSGS,(ex)Lucas,原根,Miller-Rabin,Pollard-Rho
数论入门2 另一种类型的数论... GCD,LCM 定义\(gcd(a,b)\)为a和b的最大公约数,\(lcm(a,b)\)为a和b的最小公倍数,则有: 将a和b分解质因数为\(a=p1^{a1}p ...
- 数学:乘法逆元-拓展GCD
乘法逆元应用在组合数学取模问题中,这里给出的实现不见得好用 给出拓展GCD算法: 扩展欧几里得算法是指对于两个数a,b 一定能找到x,y(均为整数,但不满足一定是正数) 满足x*a+y*b=gcd(a ...
- 扩展GCD 中国剩余定理(CRT) 乘法逆元模版
extend_gcd: 已知 a,b (a>=0,b>=0) 求一组解 (x,y) 使得 (x,y)满足 gcd(a,b) = ax+by 以下代码中d = gcd(a,b).顺便求出gc ...
- 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)
先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...
- Bzoj2154 Crash的数字表格 乘法逆元+莫比乌斯反演(TLE)
题意:求sigma{lcm(i,j)},1<=i<=n,1<=j<=m 不妨令n<=m 首先把lcm(i,j)转成i*j/gcd(i,j) 正解不会...总之最后化出来的 ...
- HDU 1576 (乘法逆元)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1576 题目大意:求(A/B)mod 9973.但是给出的A是mod形式n,n=A%9973. 解题思 ...
- UVa 11174 (乘法逆元) Stand in a Line
题意: 有n个人排队,要求每个人不能排在自己父亲的前面(如果有的话),求所有的排队方案数模1e9+7的值. 分析: <训练指南>上分析得挺清楚的,把公式贴一下吧: 设f(i)为以i为根节点 ...
- Light OJ 1067 Combinations (乘法逆元)
Description Given n different objects, you want to take k of them. How many ways to can do it? For e ...
随机推荐
- python毕业设计选题15例,马上要毕业啦,大家做好准备了没
Hi,大家好,大四的同学马上要开始毕业设计啦,大家做好准备了没! 学长给大家详细整理了最新的python计算机毕设相关选题,对选题有任何疑问,都可以问学长哦. 1. 网上商城系统 这是一个基于pyth ...
- asp.net core之实时应用
本文将介绍ASP.NET Core SignalR,这是一个强大的实时通信库,用于构建实时.双向通信应用程序.我们将探讨SignalR的基本概念.架构和工作原理,并提供一些示例代码来帮助读者更好地理解 ...
- 560.和为k的数组
1.题目介绍 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 . 子数组是数组中元素的连续非空序列. 示例 1: 输入:nums = [1,1,1], ...
- SpringBoot02:运行原理初探
@EnableAutoConfiguration @EnableAutoConfiguration:开启自动配置功能 以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 @Ena ...
- [转帖]使用 EXISTS 代替 IN 和 inner join
在使用Exists时,如果能正确使用,有时会提高查询速度: 1,使用Exists代替inner join 2,使用Exists代替 in 1,使用Exists代替inner join例子: 在一般 ...
- [转帖]windos的kafka设置账号密码
1.kafka配置文件 server.properties增加 listeners=SASL_PLAINTEXT://127.0.0.1:9092 advertised.listeners=SASL_ ...
- [转帖]Python基础之函数(四)
https://www.jianshu.com/p/168e341fb81c 一.函数定义 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段:比如常用的print(),就是内建函数:通 ...
- [转帖]使用SkyWalking监控nginx (以openresty为例)
https://www.cnblogs.com/hahaha111122222/p/15829737.html 安装使用SkyWalking先看这篇文章,地址:https://www.cnblogs. ...
- [转帖]12.计算机网络---iptables防火墙管理工具
文章目录 一.防火墙基础知识 1.1 防火墙是什么? 1.2 iptables基础知识 1.3 netfilter和iptables的关系: 1.4 新型防火墙工具:firewalld 二.iptab ...
- 解决Chrome翻译无法使用
截止2022年11月3日自己ping出的ip不可用了 可以用以下ip 172.217.215.90 172.253.115.90 142.250.126.90 142.250.10.90 142.25 ...