hint:这里所有的形如ab的都是表示a^b(a的b次方)
求解x=a^b(mod m)
本文致力于解决如下问题:求解x≡ab(mod m),其中a,b,m都是正整数。
如果b足够小,则可直接用逐次平方法求解,如果你不知道逐次平方法,可以先看一下这个方法。所以这里假设b足够大(这不是说是一个64位整数,而是可以上百上千位的一个数),大到逐次平方法也已不足以快速出解。
用素数探路的思想,先假设m是素数,那么要么a与m互素,要么m|a。前者可利用费马小定理,令b = k(m-1) + b′,其中0≤b′<m-1,则有ab≡ak(m-1)+b′≡ab′(mod m)。之后可用逐次平方法快速求解。若m|a,结果显然为0。
现在考虑要求m可以是任意数的情况。同样,若a与m互素,由上边我们可联想到欧拉公式,利用欧拉公式求解。令b = kΦ(m) + b′,其中0≤b′<Φ(m),则有ab≡akΦ(m)+b′≡ab′(mod m),之后用逐次平方法快速求解。如果a与m不互素,即gcd(a,m)>1,这种情况下应该怎么做?
注意到b如此大,而模m的不同的数最多只有m个,显而易见的,ab一定和某个很小的指数ab′模m同余,如果找到这个小的指数,就可以利用逐次平方法求解。考虑如下序列:
a0, a1, ..., am(mod m)
由鸽巢原理可知,必有一个最小的r和一个最小的s,使得ar≡ar+s(mod m),其中r+s≤m。若找到这样的r和s,那么显然有ax≡akr+x0≡akr+s+x0≡ax+s(mod m),其中x是大于或等于r的任意数。要注意的是,对任意大于或等于r的x,不存在更小的数s1,使得ax≡ax+s1(mod m)。假如有更小的这样的数s1存在,不妨设x = r+ks,因为若不这样,可以令x1 = x + x′ = r + ks,同余式两边同时乘以ax′,就变成ax1≡ax1+s1(mod m),而x1 = r+ks。所以有ax≡ar+ks≡ar≡ar+s1(mod m),其中s1<s,这与我们找到的s是最小的相矛盾,所以这样的s1是不存在的。上面的论述给出以下的一个事实:序列
a0, a1, ..., ak, ...(mod m)
实际上是这样一个序列
a0, a1, ..., ar, ar+1, ..., ar+s-1, ar, ar+1, ...(mod m