首先给大家普及一下什么是扩展欧几里德算法,它是由欧几里德算法演变的,即我们常说的辗转相除法。
代码如下:
int
gcd(
int
a,
int
b){
return
b?gcd(b,a%b):a;
}
代码一如下:
int exGcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
int r=exGcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return r;
}
int gcd(int a,int b,int &x,int &y){
if (b==0){
x=1,y=0;
return a;
}
int q=gcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
//递归最底层必定是a==gcd(a,b),所以x==1,b*y任意,令y=0,方便求解。 通过以上介绍的相邻两层递归之间线性关系,求出最初的x,y。
//找到一组数对x,y使得等式成立,但并不是最简的整数,也不是非负的。下面的题目会涉及到。
思路:一个很大的数,在进行+、* 运算时,不断的取余是不影响结果的,但是 “-” 会出现负数,只要+mod在再%mod就行了,但是 /(除法)需要求逆元。所以这个就是个模板题。
代码如下:
思路一(正解):
#include
#include
#define m 9973
int exGcd(int a,int b,int &x,int &y)
{
if(b==0)
{
x=1;y=0;
return a;
}
int r=exGcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
return r;
}
int main()
{
int n,b,t,x,y;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&b);
exGcd(b,m,x,y);
x=(x%m+m)%m; //默认
printf("%d\n",(x*n)%m); //正常情况这里要求x*A的,但是A比较大给了A%m取余了。
}
return 0;
}
//当然也可以从原理上分析这个题目因为A%B==0,假设A/B=T;模拟一下T的值就可以了,易犯错误(A/B)%9973!=(A%9973)/(B%9973)
#include
int main()
{
long long a,b;
int k=9973;
long long w;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&a,&b);
int t=1;
while(w%k!=a)
w=(t++)*b;
printf("%I64d\n",(t-1)%k);
}
return 0;
}