看了数论第一章,终于搞懂了扩展欧几里德,其实就是普通欧几里德的逆推过程。
// ax+by = gcd(a,b) ->求解x,y 其中a,b不全为0,可以为负数
// 复杂度:O(log2a)
void extendgcd(ll a,ll b,long long &x,long long &y) { if(a%b==0) { //到了终止条件 x=0; y=1; return ; } extendgcd(b,a%b,x,y); long long tmpx; tmpx=y; y=x-(a/b)*y; x=tmpx; }
还有大神写的超简洁版本:
//ax + by = gcd(a,b) //传入固定值a,b.放回 d=gcd(a,b), x , y void extendgcd(long long a,long long b,long long &d,long long &x,long long &y) { if(b==0){d=a;x=1;y=0;return;} extendgcd(b,a%b,d,y,x); y-=x*(a/b); }
//顺便加两个公式
//a>1,m,n>0,gcd( am - 1 ,an - 1 ) = agcd(m,n) -1
//a>b,gcd(a,b) = 1, gcd(am-bm,an-bn) = agcd(m,n) - bgcd(m,n)