欧几里德

基本思想:gcd(q,r)=gcd(r,q%r);
证明,设q、r的最大公因数为a,则q=xa,r=ya,xy互质
不妨设x>y(显然如果小于会在一次gcd运算后交换)
则q%r=(x%y)*a
显然,其与r的最大公因数仍是a
时间复杂度:接近于log

代码

ll gcd(ll q,ll r){if(r==0){return q;}return gcd(r,q%r);
}

扩展欧几里德

对于q,r 及其最大公因数g,不定方程:
aq+br=g
必定存在无限多对整数a、b的解(证明会在下面给出)
拓展欧几里德就是用于求出这个a与b的一对特殊值
对于递归转移,有如下方程:

gcd(q,r):a*q+b*r=g;
gcd(r,q%r):A*r+B*(q%r)=g;

任务是得到ab与AB之间的转移
又因为:

q%r=q-r*(q/r);

方程联立,可解得:

(B-a)*q+(A-b-(x/y)*B)*r=0;

各系数为0;
即:

a=B;
b=A-(q/r)*B;

问题得到解决

代码

ll gcd(ll q,ll r){//a和b全局或传参皆可if(r==0){b=0;a=1;return q;}ll c=gcd(r,q%r);trans=a;//中转一下a=b;b=trans-(q/r)*b;return c;
}

回到前面的问题:

对于q,r 及其最大公因数g,不定方程:
aq+br=g
必定存在无限多对整数a、b的解

可以通过上面这个代码发现:
不断辗转取模,q、r单调递减
一定会达到边界值(r==0)
那么就可以往回递归a与b
其值是存在且确定的

应用:求解不定方程

对于关于整数a、b的不定方程:
am+bn=w

若mn的最大公因数为g
则m和n可以分别写为k1g和k2g(k1k2均为整数)
那么原方程可以改写为:
ak1g+bk2g=w

显然,当w不能整除g时,方程无解(反证易得)

当w整除g时:
w可以写为cg,c为整数
由拓展欧几米德可知:
ak1g+bk2g=g 恒有解
两边同乘c:
cak1g+cbk2g=cg
即:
cak1g+cbk2g=w
显然这里的ca与cb就是一对整数解

综上,我们得出结论:

对于关于整数a、b的不定方程:
am+bn=w
当且仅当w整除g时,方程有解
其中一对特殊解为ca,cb(字母定义同上)

从特殊解得到普遍解

那么如何从特殊解得到普遍解呢?
设当前已知的解为x0,y0,另一对解为x,y
那么:

x0m+y0n=w;
xm+yn=w

两式相减:
(x0-x)m+(y0-y)n=0;
设k1=x0-x,k2=y0-y;
那么k1,k2就是两个解上下浮动的间隔
再移项得到
k1m=-k2n
左边是m的倍数
右边是n的倍数
那么不难看出,等号两边是m和n的公倍数
那么取m与n的最小公倍数时,k1k2取到绝对值最小的值
最小公倍数可以写成mn/gcd(m,n)
即:
k1(min)*m=mn/gcd(m,n)
即:k1(min)=n/gcd(m,n)
同理k2(min)=m/gcd(m,n)

综上
若一组特殊解为x0,y0
则所有解的集合是:

x0+tn/gcd(m,n)
y0+t
m/gcd(m,n)

t为同一个整数;
注意x0对应的是m,换句话说就是交叉对应

代码

(这题是洛谷P1516 青蛙的约会的题解)

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <string>
#include <iostream>
#include <climits>
#define ll long long
using namespace std;
const int M = 500050;
const int N = 500050;
const ll mod = 1000000007;
ll x,y,m,n,l;
ll a,b,g,p,w,trans;
ll gcd(ll q,ll r){if(r==0){b=0;a=1;return q;}ll c=gcd(r,q%r);trans=a;a=b;b=trans-(q/r)*b;return c;
}
int main() {scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&l);p=n-m;w=x-y;if(p<0){w=-w;p=-p;}g=gcd(p,l);if(w%g){printf("Impossible");return 0;}
//  printf("a=%lld g*l=%lld p=%lld l=%lld g=%lld b=%lld w=%lld\n",a,g*l,p,l,g,b,w);while(a<0) a+=(g*l);ll k=w/g;a*=k;if(a<0) a+=(((-a)/(l/g))+1)*(l/g);//寻找到最小正整数解a%=(l/g);printf("%lld",a);return 0;
}
/*
*/

thanks for reading!

特别鸣谢:lq、qyt、wyx三位大佬对证明过程中问题的指出awa

数论:扩展欧几里德(洛谷P1516 青蛙的约会)相关推荐

  1. 洛谷 P1516 青蛙的约会

    https://www.luogu.org/problemnew/show/P1516#sub 题意还是非常好理解的..... 假如这不是一道环形的跑道而是一条直线,你会怎样做呢? 如果是我就会列一个 ...

  2. POJ 1061 BZOJ 1477 Luogu P1516 青蛙的约会 (扩展欧几里得算法)

    POJ 1061 BZOJ 1477 Luogu P1516 青蛙的约会 (扩展欧几里得算法) 手动博客搬家: 本文发表于20180226 23:35:26, 原地址https://blog.csdn ...

  3. 洛谷P1244青蛙过河

    洛谷P1244青蛙过河 题目描述 有一条河,左边一个石墩(A 区)上有编号为 1,2,-,n 的 n 只青蛙,河中有 k 个荷叶(C 区),还有 h 个石墩(D 区),右边有一个石墩(B 区),n 只 ...

  4. P1516 青蛙的约会 [exgcd]

    P1516 青蛙的约会 题意:在一个长为\(l\)的环上面有两只青蛙,一只出发点为\(x\),一次跳\(m\),另一只出发点为\(y\),一次跳\(n\),求相遇时间. 这个长为\(l\)的环不难想到 ...

  5. 【洛谷P1516】青蛙的约会

    青蛙的约会 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情 ...

  6. 洛谷P1244 青蛙过河 DP/思路

    又是一道奇奇怪怪的DP(其实是思路题). 原文戳>>https://www.luogu.org/problem/show?pid=1244<< 这题的意思给的挺模糊,需要一定的 ...

  7. 青蛙的约会(洛谷-P1516)

    题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件很重要的事情,既没有问清 ...

  8. 又是毕业季I 【O(1)数论】(洛谷P1372题题解,Java语言描述)

    题目要求 P1372题目链接 分析 膜大佬的证明,数论学得好,人生真自信! AC代码(Java语言描述) import java.util.Scanner;public class Main {pub ...

  9. 洛谷P1244青蛙过河题解

    我用的是C++来解 其实这道题很简单,只要弄清楚关系就行,和汉诺塔问题相似.不用细想顺序(青蛙就是乱跳),可将青蛙作为一个整体来想. 我们用f[h][k]表示h个石墩和k片荷叶最多的青蛙数 f[0][ ...

最新文章

  1. 中国AI已进入迷茫阶段!从技术到科学,AI该何去何从?
  2. 解决启动httpd报: apr_sockaddr_info_get() failed for错误
  3. android clipdrawable 小例子
  4. 【转载】如何使用STM32的窗口看门狗
  5. 面进了心心念念的国企!以为TM上岸了!干了1年!我却再次选择回到互联网大厂内卷!...
  6. spark 源码分析之十九 -- DAG的生成和Stage的划分
  7. core dump python_python 源码笔记 ---- freeblock
  8. 【word】为什么word分两栏的最后一页左边一栏没写完跑到右边去了
  9. 152-Maximum Product Subarray
  10. mysql插入用户 5.7_mysql 5.7 用户添加与权限管理
  11. 过滤器和拦截器的区别_拦截器和过滤器的区别
  12. linux7重启network,mmp的 rhel7 network重启一直失败,求原因!!!
  13. 2017华为软挑——遗传算法
  14. iOS 第三方 汇总
  15. 涅普之rce(远程代码控制)
  16. 用c#开发Android应用(二)——运行Hello World!
  17. ICME 论文Latex模版要求
  18. OpenLayers3 地图图层(Layers) 详解
  19. 手把手解决“npm、node不是内部或外部命令,也不是可运行的程序或批处理文件”
  20. SuperMap iDesktop常见问题解答集锦(五)

热门文章

  1. java aspose重叠_Aspose.Words - 在特定位置合并两个文档
  2. linux检查系统硬件信息命令,Linux查看系统信息(硬件信息, 系统设置信息等) 命令 | Soo Smart!...
  3. 实现链栈的各种基本运算的算法_LeetCode基础算法题第78篇:如何不用加减号实现两数的加法运算?...
  4. mysql序列increment_MySQL 序列 AUTO_INCREMENT
  5. 3dsmax子菜单无法选择_3DsMax—用平面图片制作3D模型
  6. oracle 监听 无法连接,解决ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务...
  7. MBR的Linux分区机制启动过程,linux系统启动流程(MBR)
  8. linux管理Windows文件,Linux与Windows互传文件,用户组管理和用户管理
  9. matlab eval函数_matlab自动给变量命名
  10. leetcode860. 柠檬水找零