靠!我果然不适合密码学这一类的,真是丢人,我的导师还是原来学数学的,还是教密码学,还是写过信安数学基础在这类书的人,真是丢人!!!
好多下标不好打字,我还是写上截图吧
- 课本上和老师讲的算法都是基于x,y的递推式,没看贝祖等式的证明,也不知道怎么来的,还是这个思路清晰,就是按照我们手算的思路进行的。
- 总之,扩展欧几里得算法的思路就是先按照欧几里得算法计算出gcd(终止条件就是b=0,a=gcd,这个条件也是接下来的初始条件),利用这个我们可以得到a1+b0=gcd,也就是说是xn=0,yn=1,根据递推式就可以得到xn-1,yn-1,进而得到x,y。最终算法也是采用的递归函数。
int exgcd(int a, int b, int& s, int& t)
{
if (b == 0)
{
s = 1;
t = 0;
return a;
}
int gcd = exgcd(b, a % b, s, t);
int temp = s;
s = t;
t = temp - (a / b) * t;
return gcd;
}
终于解决了这个问题,太笨了。。。。
哦哦哦哦哦哦忘了忘了,参考某个ACM大佬的博客 传送门
那个啥我又看了看关于直接算出每一步的s,t,就是用s,t的递推式做的
这个就是基于几个递推式
设s1是前一次算的s,s2是这一次算的s,同理t,r:
- sj=sj-2 - sj-1*qj
- tj= tj-2 - tj-1*qj
- rj=rj-2 - rj-1*qj
不会推导的,长得都一样,也挺好记的,毕竟r我们是知道的
然后程序代码
long long exgcd2(long long a, long long b, long long& s, long long& t)
{
long long s1 = 1;
long long s2 = 0;
long long t1 = 0;
long long t2 = 1;
long long r1 = a;
long long r2 = b;
long long q;
long long tempr;
long long temps;
long long tempt;
while (r2 != 0)
{
q = r1 / r2;
tempr = r1 - r2 * q;
temps = s1 - s2 * q;
tempt = t1 - t2 * q;
r1 = r2;
s1 = s2;
t1 = t2;
r2 = tempr;
s2 = temps;
t2 = tempt;
}
s = s1;
t = t1;
return r1;
}
运行结果就是这样啦:
ending!扩展欧几里得算法,俺去学整除的进一步性质!