扩展欧几里得
- 裴蜀定理:对任何整数 a、b 和它们的最大公约数 d,关于未知数 x 和 y 的线性不定方程: 有解(当且仅当 是 的倍数)
- 裴蜀定理应用:如果 有解,那么
- 辗转相除法
-
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }
- 如果得到 的某一特解 X,那么令 ,可知 在 上有唯一解,用 就可以求出最小非负整数解 了
板子
已知
和
,求解方程
注意:求出的不是最小解
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL extgcd(LL a, LL b, LL &x, LL &y) //扩展欧几里得,返回最大公约数(x,y 是变量参数直接返回)
{
LL d,t;
if(b==0)
{
x=1;
y=0;
return a; //返回最大公约数
}
d=extgcd(b,a%b,x,y);
t=x-a/b*y;
x=y;
y=t;
return d; //返回最大公约数
}
int main()
{
LL a,b,x,y,d; //d 是最大公约数
cin>>a>>b;
d=extgcd(a,b,x,y);
cout<<a<<"*"<<x<<"+"<<b<<"*"<<y<<"="<<d<<endl;
return 0;
}
青蛙的约会
式子简单变形即可
必须要判断负数!!!!!!(70
惨案TAT)
#include <bits/stdc++.h>
#define int long long
using namespace std;
int x,y,m,n,L,X,Y;
int exgcd(int a,int b,int &x,int &y){
int d,t;
if(b==0){
x=1,y=0;
return a;
}
d=exgcd(b,a%b,x,y);
t=x-a/b*y;
x=y;y=t;
return d;
}
signed main(){
//freopen("a.in","r",stdin);
scanf("%lld%lld%lld%lld%lld",&x,&y,&m,&n,&L);
int k=n-m,a=x-y;//简单式子变形
if(k<0)
{
k=-k;
a=-a;
}//处理负数
int d=exgcd(k,L,X,Y);
int r=L/d;
if(a%d!=0){
printf("Impossible");
return 0;
}
else{
printf("%lld\n",(a/d*X%r+r)%r);
return 0;
}
}