数论学习笔记

ExGCD:

目的:求形如 Ax+By=C 的不定方程的通解

有解判断:

方程有解的充要条件是 Gcd(a,b)|C,可以使用数论知识证明

问题简化:

将问题简化为求 Ax+By=Gcd(a,b) 的通解,先求他的一组解。

思路及证明:

使用递归的思想减小A和B的值,直至方程变为x=Gcd(x,0)的形式。

已知:

Gcd(a,b)=Gcd(b,a%b)

考虑:

Ax1+By1=Gcd(A,B)

Bx2+(A%B)y2=Gcd(B,A%B)

然后寻找(x1,y1)(x2,y2)的递推关系。

a%b=abb带入得:

A(x1y2)+B(y1x2+ABy2)=0

由于我们只需要每个递归状态的一组解即可,所以我们可以直接使用

x1=y2

y1=x2ABy2

进行递归,得到一组特解。

求通解:

已知:

Ax1+By1=C

Ax2+By2=C

两式做差:

Ax1+By1=Ax2+By2

g=Gcd(A,B)

则:

Ag(x1x2)+Bg(y1y2)=0

得通解:

x=x0+kBg
y=y0kAg

例题:

青蛙的约会

本题需要求出x的最小正整数解,可以采用M=|Bg|, x=(x0来求出最小整数解x,注意模数一定取正数!还有注意开longlong

#include<bits/stdc++.h>
#define int long long
using namespace std;
int x, y;
int exgcd(int a, int b){
if (b == 0){
x = 1;y = 0;return a;
}
int g = exgcd(b, a%b);
int tmp = x;
x = y;
y = tmp - a / b * y;
return g;
}
signed main(){
int x0, y0, m, n, l;cin>>x0>>y0>>m>>n>>l;
int g = exgcd(m - n, l);//方程形如(m-n)x+ly=(y0-x0)
if((y0 - x0) % g) cout<<"Impossible"<<endl;
else{
x *= (y0 - x0) / g;
l = abs(l / g);
x = (x % l + l) % l;
cout<<x<<endl;
}
return 0;
}
posted @   hcx1999  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
点击右上角即可分享
微信分享提示