exgcd入门以及同余基础

gcd,欧几里得的智慧结晶,信息竞赛的重要算法,数论的...(编不下去了

讲exgcd之前,我们先普及一下同余的性质:

  1. ,那么
  2. ,且p1,p2互质,

有了这三个式子,就不用怕在计算时溢出了。

下面我会用分别表示a与b的最大公约数与最小公倍数。

首先会来学扩欧的同学肯定都会欧几里得算法(即辗转相除法)了吧

而通过观察发现:,先除后乘防溢出。

所以的代码如下:

 inline int gcd(int a,int b)
{return (b==)?a:gcd(b,a%b);}
inline int lcm(int a,int b)
{return a/gcd(a,b)*b;

讲exgcd之前先引入一种方程——不定方程

所谓不定方程,是指未知数的个数多于方程个数,且未知数受到某些限制(如要求是有理数、整数或正整数等等)的方程或方程组。

————百度百科

就是形如的方程,其中a,b,c已知。

1.判断是否有解

如果,那么方程无解。

2.转化

方程可转化为

其中

3.求一组特解

接着就用到了exgcd。

我们知道gcd有一个性质

如果,一直循环下去,b将等于0,那么x将等于c/a,y=0。

 inline void exgcd(int a,int b,int c)
{
if(!b)
{x=c/a;y=;return;}
exgcd(b,a%b,c);
x=y;
y=(c-a*x)/b;
return;
}

这就求出了一组特解。

exgcd的模板我也在这摆出来

 inline void exgcd(int a,int b)
{
if(!b)
{x=;y=;return;}
exgcd(b,a%b);
k=x;x=y;
y=k-a/b*y;
return;
}

这是求时用的,后面讲同余方程会讲。

4.构造通解

我们假设x1,y1是我们求出的一组特解,那么

    


同余类问题

1.单个同余方程

求的是关于x的解

转化一下,就成了,就可以直接套exgcd模板。

2.同余方程组

1.有解的充要条件

2.

下式减上式得

再用exgcd求出y1和y2,

3.关于通解

所有的x mod lcm(p1,p2)有唯一解,这样就可以通过特解,求通解了。

4.至于式子更多的同余方程组,就先联立两个,就可以得出新的方程

再联立下一个。


exgcd用处及题目讲解

1.求同余方程的解

例如这道题P1082

这是一道裸的扩欧模板题,变形之后就是求

套模板即可。

 inline void exgcd(int a,int b)
{
if(b==)
{x=;y=;return;}
exgcd(b,a%b);
k=x;x=y;
y=k-a/b*y;
return;
}
int main()
{
int n,m;
read(n),read(m);
exgcd(n,m);
printf("%d",(x+m)%m);
}

还有一道模板P1516

仔细观察,推一下后我们发现,这在就是在求的解。

进而可以推出

合并同类项后

把一些东西移到左边来后

把(x-y),(n-m)各看成一个整体后,问题就成了解一个不定方程。

 inline int exgcd(long long a,long long b)
{
if(b==)
{x=;y=;return a;}
ans=exgcd(b,a%b);
k=x;x=y;
y=k-a/b*y;
return ans;
}
int main()
{
long long x1,y1,m,n,l;
read(x1),read(y1),read(m),read(n),read(l);
if(n-m<)swap(x1,y1);
exgcd(std::abs(n-m),l);
if((x1-y1)%ans!=)
printf("Impossible");
else
printf("%lld",((x*((x1-y1)/ans))%(l/ans)+(l/ans))%(l/ans));
}

还有一道也是模板P4777,涉及同余方程组求解,上面已详细的讲了,近期我也会发一篇中国剩余定理的博客

 inline long long mul(long long a,long long b,long long mod)
{
long long res=;
while(b>)
{
if(b&) res=(res+a)%mod;
a=(a+a)%mod;
b>>=;
}
return res;
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
if(!b)
{x=;y=;return a;}
long long gcd=exgcd(b,a%b,x,y);
k1=x;x=y;
y=k1-a/b*y;
return gcd;
}
int main()
{
io::begin();
io::read(n);
for(register int i=;i<=n;i++)
io::read(b1[i]),io::read(a1[i]);
long long x,y,k;
long long m=b1[],ans=a1[];
for(int i=;i<=n;i++)
{
long long a=m,b=b1[i],c=(a1[i]-ans%b+b)%b;
long long gcd=exgcd(a,b,x,y);
long long p=b/gcd;
x=mul(x,c/gcd,p);
ans+=x*m;
m*=p;
ans=(ans%m+m)%m;
}
printf("%lld",(ans%m+m)%m);
}

2.扩欧求逆元

这是一种很重要的算法,至于逆元怎么跟扩欧扯上关系,大家可以点这里乘法逆元及两道模板题详解

这里就不多赘述了,大家可以用扩欧a一下P3811,P2613。


我要讲的讲完了,如果觉得讲的还好,请关注我的blog,谢谢

扩展欧几里得(exgcd)与同余详解的更多相关文章

  1. 同余问题(一)——扩展欧几里得exgcd

    前言 扩展欧几里得算法是一个很好的解决同余问题的算法,非常实用. 欧几里得算法 简介 欧几里得算法,又称辗转相除法. 主要用途 求最大公因数\(gcd\). 公式 \(gcd(a,b)=gcd(b,a ...

  2. 浅谈扩展欧几里得[exgcd] By cellur925

    关于扩展欧几里得从寒假时就很迷,抄题解过了同余方程,但是原理并不理解. 今天终于把坑填上了qwq. 由于本人太菜,不会用markdown,所以这篇总结是手写的(什么).(字丑不要嫌弃嘛) ****** ...

  3. 扩展欧几里得(exgcd)-求解不定方程/求逆元

    贝祖定理:即如果a.b是整数,那么一定存在整数x.y使得ax+by=gcd(a,b).换句话说,如果ax+by=m有解,那么m一定是gcd(a,b)的若干倍.(可以来判断一个这样的式子有没有解)有一个 ...

  4. 扩展欧几里得 exGCD

    Elementary Number Theory - Extended Euclid Algorithm Time Limit : 1 sec, Memory Limit : 65536 KB Jap ...

  5. 数论--扩展欧几里得exgcd

    算法思想 我们想求得一组\(x,y\)使得 \(ax+by = \gcd(a,b)\) 根据 \(\gcd(a,b) = \gcd(b,a\bmod b)\) 如果我们现在有\(x',y'\) 使得 ...

  6. J - 青蛙的约会(扩展欧几里得)

    https://vjudge.net/contest/218366#problem/J 第一步追及公式要写对:y+nk-(x+mk)=pL => (n-m)k+lp=x-y 可以看出扩展欧几里得 ...

  7. EXGCD 扩展欧几里得

    推荐:https://www.zybuluo.com/samzhang/note/541890 扩展欧几里得,就是求出来ax+by=gcd(x,y)的x,y 为什么有解? 根据裴蜀定理,存在u,v使得 ...

  8. exgcd扩展欧几里得求解的个数

    知识储备 扩展欧几里得定理 欧几里得定理 (未掌握的话请移步[扩展欧几里得]) 正题 设存在ax+by=gcd(a,b),求x,y.我们已经知道了用扩欧求解的方法是递归,终止条件是x==1,y==0: ...

  9. UVA 12169 Disgruntled Judge 枚举+扩展欧几里得

    题目大意:有3个整数 x[1], a, b 满足递推式x[i]=(a*x[i-1]+b)mod 10001.由这个递推式计算出了长度为2T的数列,现在要求输入x[1],x[3],......x[2T- ...

随机推荐

  1. 【HANA系列】SAP HANA XS使用JavaScript编程详解

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA XS使用Jav ...

  2. 在原有数据库中使用 CodeFirst

    一.为当前实体模型启用数据迁移 1.Enable-Migrations -ContextTypeName EME.DBHelper.StoreContext(数据访问上下文) 2. Add-Migra ...

  3. NT路径,DOS路径和Device路径互相转换

    项目中遇到的比较奇葩的问题,从网上找到一份源码,https://blog.csdn.net/qq125096885/article/details/70766206 稍微整理了下,VS可以直接编译 # ...

  4. 软工+C(4): Alpha/Beta换人

    // 上一篇:超链接 // 下一篇:工具和结构化 注:在一次软件工程讨论课程进度设计的过程中,出现了这个关于 Alpha/Beta换人机制的讨论,这个机制在不同学校有不同的实施,本篇积累各方观点,持续 ...

  5. C# 使用CsvHelper读取.csv文件

    1,先到包管理器下载 安装CsvHelper. 2,创建一个与csv文件字段名称相同的类 public class SurveyInfoModel { public string DIST_CD { ...

  6. vue配置jquery和bootstarp

    jquery: 1.npm install jquery --save-dev 引入jquery. 2.在webpack.base.conf.js中添加如下内容: var webpack = requ ...

  7. Ubuntu命令整理

    linux下find命令的使用和总结 - CS408 - 博客园 ubuntu 命令简写和全称 su:Swith user  切换用户,切换到root用户 cat: Concatenate  串联 u ...

  8. python多线程中join()方法和setDaemon()方法的区别

    """ join()方法:主线程A中,创建了子线程B,并且在主线程中调用了B.join()方法,那么主线程A会在调用的地方等待,直到子线程B完成操作后,才可以接着往下执行 ...

  9. P1140 相似基因 (dp)

    题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了44种核苷酸,简记作A,C,G,TA,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务 ...

  10. ReactNative开发笔记(持续更新...)

    本文均为RN开发过程中遇到的问题.坑点的分析及解决方案,各问题点之间无关联,希望能帮助读者少走弯路,持续更新中... (2019年3月29日更新) 原文链接:http://www.kovli.com/ ...