今天是我来到纪中的第十七天
今天听了一个讲座
讲的内容呢-是数论
什么gcd exgcd 高斯消元 ex卢卡斯 卢卡斯.....
以前学过了,今天作为一个巩固
可是我10点四十五(也就是现在)就回来了。。。
GCD即Greatest Common Divisor,最大公约数。最大公约数即能同时整除给定两个整数的最大正整数。特殊地:gcd(a,0)=a。求解最大公约数通常使用辗转相除法。下面是辗转相除法的代码实现:
1 typedef long long LL; 2 LL gcd(LL a, LL b) { 3 return b ? gcd(b, a % b) : a; 4 }
辗转相除法得到的余数序列增长速度比斐波那契数列更快,已知斐波那契的增长是指数级别,则辗转相除法的复杂度是对数级别。
辗转相除法的证明:
2.反证法证明m-kn和n互质:假设m-kn和n不互质,用数学语言描述为:假设存在整数x,y,d,其中d>1,使得m-kn=xd,n=yd。那么有m=kn+xd=kyd+xd=(ky+x)d,从而a=mc=(ky+x)cd,b=nc=ycd,则gcd(a,b)=cd≠c,与前设矛盾。故m-kn和n互质得证,也就证明了gcd(a,b)=gcd(b,r)。
EXGCD
贝祖定理(Bezouts Identity):若设a,b是不全为0的整数,则存在整数x,y,使得ax+by=gcd(a,b),(a,b)代表最大公因数,则设a,b是不全为零的整数,则肯定存在整数x,y,使得ax+by=(a,b)。这个式子称为贝祖等式。
EXtend GCD 即扩展欧几里得算法,它可以用于解关于x,y的贝祖等式。
EXGCD的可行性
当a=0时,ax+by=gcd(a,b)=gcd(0,b)=b,这时可以解出y=1而x为任意。同理可得b=0时,解得x=1而y为任意。当a,b都不为0时:
a或b为0即迭代求解的出口,迭代过程用代码表示如下:
typedef long long LL; // ver 1 // 返回值为gcd(a,b),x和y即求出的特解 LL exgcd(LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1; y = 0; return a; } LL ans = exgcd(b, a % b, x, y); //这里通过迭代求出了一组解x,y,这组解对应上面推导过程中的x2和y2。 LL temp = x; x = y; y = temp - a / b * y; return ans; } // ver 2 // 在熟悉了推导过程之后,我们可以利用引用的性质得到更为简洁的ver2写法 LL exgcd(LL a, LL b, LL &x, LL &y) { if (b == 0) { x = 1; y = 0; return a; } LL ans = exgcd(b, a % b, y, x); y -= a / b * x; return ans; }