基本问题:ax+by=gcd(a,b)
关键点:a^-1(a的模逆元)*a=1(mod b),只要解出a的逆元,问题就可以迎刃而解了。
原理1:费马小定理:a^p(p是质数)=a(mod p)
变形:a^(p-1)=1(mod p)
a^(p-2)*a=1(mod p)
所以:a^-1=a^(p-2)(mod p)
设p为一很大的质数,快速幂求解。
原理2:拓展欧几里得算法:gcd(a,b)=gcd(b,a%b)
又:gcd(a,b)=ax+by
gcd(b,a%b)=b*x1+(a-a/b*b(取整))*y1
=a*y1+b*(x1-a/b*y1)
所以:x=y1
y=x1-a/b*y1
递归求解。
参考程序:
#include<cstdio>
#define oo 2147483647
int a,b,x,y;
int exgcd (int a,int b,int &x,int &y){
if (b==0){
x=1;y=0;return a;
}else{
int d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
}
int ksm(int x,int ex){
if (ex==1)return x;
int k=ksm(x,ex/2)%b;
return ((k*k)%b*(ex%2==1?x:1))%b;
}
int main(){
scanf("%d %d",&a,&b);
int k=exgcd(a,b,x,y),n=b;
printf("%d\n",(x+n)%n);
int t=ksm(a,oo-2);
printf("%d",t);
return 0;
}