ZZ为NTL库提供的一个长整数类型,若不要求对大整数进行操作,则将ZZ替换为int或long即可
欧几里得算法:
ZZ Euclid1(Vec<ZZ>& x, Vec<ZZ>& y, Vec<ZZ>& z, Vec<ZZ>& k, long* n,ZZ p, ZZ q) //Euclid算法,求最大公因子
//x存被除数,y存除数,z存余数
{
long i;
if(p>=q)
{
x[0] = p;
y[0] = q;
}
else
{
x[0] = q;
y[0] = p;
}
for (i = 0;(x[i] % y[i])>0; i++)
{
z[i] = x[i] % y[i];
k[i] = x[i] / y[i];
x[i + 1] = y[i];
y[i + 1] = z[i];
}
k[i] = 1;
n[0] = i;
return y[i];
}
欧几里得拓展算法:
该算法本身为欧几里得算法的逆算法,通过对欧几里得步骤取逆可得
代码如下:
void Euclid_extension(ZZ a,ZZ b,ZZ c,Vec<ZZ> k) // k为上面Euclid1函数得到的数组k
//a,b为两个求最大公因子的数,c为最大公因子
{
f1 = k[i];
f2 = k[i - 1];
for(i=n[0]-2;i>=0;i--)
{
f1 = f2;
f2 = f2 * k[i] + k[i + 2];
}
if (a > b)
{
d = f1;
x = -f2;
}
else
{
d = -f2;
x = f1;
}
cout<<a<<"*"<<d<<"+"<<b<<"*"<<x<<"="<<c<<endl;
}