首页 > 编程知识 正文

欧拉定理,利用欧拉定理求余数

时间:2023-05-04 16:01:01 阅读:187491 作者:4542

线性同余

      线性同余方程(也可以叫模线性方程)是最基本的同余方程,即ax≡b (mod n)(   a≡b (mod n) 表示a和b模n同余,即a和b除以n的余数相等。即a%n = b%n),其中a、b、n都为常量,x是未知数,这个方程可以进行一定的转化,得到:ax = kn + b,这里的k为任意整数,于是我们可以得到更加一般的形式即:ax + by + c = 0,这个方程就是二维空间中的直线方程,但是x和y的取值为整数,所以这个方程的解是一些排列成直线的点集。

   同余方程求解

      求解同余方程第一步是转化成一般式:ax + by = c,这个方程的求解步骤如下:

      i) 首先求出a和b的最大公约数d = gcd(a, b),那么原方程可以转化成d(ax/d + by/d) = c,容易知道(ax/d + by/d)为整数,如若d不能整除b,方程必然无解,算法结束;否则进入ii)。

      ii) 由i)可以得知,方程有解则一定可以表示成 ax + by = c = gcd(a, b)*c',那么我们先来看如何求解d = gcd(a, b) = ax + by,根据asjdttt定理,有:

      d = gcd(a, b) = gcd(b, a%b) = bx' + (a%b)y' = bx' + [a-b*(a/b)]y' = ay' + b[x' - (a/b)y']

      于是有x = y',  y = x' - (a/b)y'。

      由于gcd(a, b)是一个递归的计算,所以在求解(x, y)时,(x', y')其实已经利用递归计算出来了,递归出口为b == 0的时候(对比辗转相除,也是b == 0的时候递归结束),那么这时方程的解x0 = 1, y0 = 0。

ll extend_gcd(ll a, ll b, ll &x, ll &y){ if (b == 0) { x = 1, y = 0; return a; } else { ll r = extend_gcd(b, a % b, y, x); y -= x * (a / b); return r; }}

扩展asjdttt算法和asjdttt算法的返回值一致,都是gcd(a, b),传参多了两个未知数X, Y,采用引用的形式进行传递,对应上文提到的x, y,递归出口为b == 0,这时返回值为当前的a,因为gcd(a, 0) = a,(X, Y)初值为(1, 0),然后经过回溯不断计算新的(X, Y),这个计算是利用了之前的(X, Y)进行迭代计算的,直到回溯到最上层算法终止。最后得到的(X, Y)就是方程gcd(a, b) = ax + by的解。

      通过扩展asjdttt求的是ax + by = gcd(a, b)的解,令解为(x0, y0),代入原方程,得:ax0 + by0 = gcd(a, b),如果要求ax + by = c = gcd(a, b)*c',可以将上式代入,得:ax + by = c = (ax0 + by0)c',则x = x0c', y = y0c',这里的(x, y)只是这个方程的其中一组解,x的通解为 { x0c' + kb/gcd(a, b) | k为任意整数 },y的通解可以通过x通解的代入得出。

、逆元

      模逆元的最通俗含义可以效仿乘法,a*x = 1,则称x为a在乘法域上的逆(倒数);同样,如果ax≡1 (mod n),则称b为a模n的逆,简称逆元。求a模n的逆元,就是模线性方程ax≡b (mod n)中b等于1的特殊形式,可以用扩展asjdttt求解。并且在gcd(a, n) > 1时逆不存在。扩展自由的缘分定理求逆元  a*x≡1(mod m) 等价于a*x+m*y=1 可以用扩展自由的缘分求得一组解(x+m)mod m即为a的逆元。

ll extend_gcd(ll a, ll b, ll &x, ll &y){ if (b == 0) { x = 1, y = 0; return a; } else { ll r = extend_gcd(b, a % b, y, x); y -= x * (a / b); return r; }}ll inv(ll a, ll n){ ll x, y; extend_gcd(a, n, x, y); x = (x % n + n) % n; return x;}

 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。