同余问题
1. 同余定义
给定整数
m
m
m ,若两个整数
a
,
b
a,b
a,b 除以
m
m
m 所得余数相同,称
a
a
a 和
b
b
b 对模
m
m
m 同余,表示为:
a
≡
b
(
m
o
d
m
)
a ≡ b(\ mod \ m)
a≡b( mod m)。
若一个整数集合中所有数模
m
m
m 的余数相同,这个集合中的数都称为模
m
m
m 的同余类。每个同余类中的任意两个整数对模
m
m
m 同余。
定理
1
1
1 :
a
≡
b
(
m
o
d
m
)
a ≡ b(\ mod \ m)
a≡b( mod m) ,当且仅当
m
∣
a
−
b
m|a-b
m∣a−b 。
证明:
设
r
r
r 为
a
,
b
a,b
a,b 模
m
m
m 的余数,所有可以得到
a
=
k
1
×
m
+
r
,
b
=
k
2
×
m
+
r
,
a
−
b
=
(
k
1
−
k
2
)
×
m
a=k_1\times m+r,b=k_2\times m+r,a-b=(k_1-k_2)\times m
a=k1×m+r,b=k2×m+r,a−b=(k1−k2)×m ,满足
m
∣
a
−
b
m|a-b
m∣a−b ,反之亦然。
定理
2
2
2 :
a
≡
b
(
m
o
d
m
)
a ≡ b(\ mod \ m)
a≡b( mod m) ,当且仅当存在整数
k
k
k ,使得
a
=
b
+
k
×
m
a=b+k\times m
a=b+k×m 。
证明:
与定理 1 1 1 类似, a = k 1 × m + r , b = k 2 × m + r , a + k 2 × m + r = k 1 × m + r + b a=k_1\times m+r,b=k_2\times m+r,a+k_2\times m+r=k_1\times m+r+b a=k1×m+r,b=k2×m+r,a+k2×m+r=k1×m+r+b ,即 a = b + ( k 1 − k 2 ) × m = b + k × m a=b+(k_1-k_2)\times m=b+k\times m a=b+(k1−k2)×m=b+k×m 。
2. 同余有关定理
(1)欧拉定理
若正整数
a
,
n
a,n
a,n 互质,则:
a
φ
(
n
)
≡
1
(
m
o
d
n
)
a^{\varphi(n)}≡1(\ mod \ n)
aφ(n)≡1( mod n),
φ
(
n
)
\varphi(n)
φ(n) 为欧拉函数,表示
1
∼
n
1 \sim n
1∼n 中和
n
n
n 互质的数的个数。
证明:
1
∼
n
1 \sim n
1∼n 中,与
n
n
n 互质的数有
φ
(
n
)
\varphi(n)
φ(n) 个,设
x
1
,
x
2
,
x
3
…
…
x
φ
(
n
)
x_1,x_2,x_3……x_{\varphi(n)}
x1,x2,x3……xφ(n) 是
1
∼
n
−
1
1\sim n-1
1∼n−1 中与
n
n
n 互质的数。再设一个集合
M
=
{
a
x
1
,
a
x
2
,
a
x
3
…
…
a
x
φ
(
n
)
}
M=\{ ax_1,ax_2,ax_3……ax_{\varphi(n)}\}
M={ax1,ax2,ax3……axφ(n)} 。下面,我们证明两个推理:
推论一:
M
M
M 中任意两个数模
n
n
n 不同余。
反证法:
如果存在两个数同余,则
a
x
p
≡
a
x
q
(
m
o
d
n
)
ax_p≡ax_q(mod \ n)
axp≡axq(mod n) ,则
n
∣
(
a
x
p
−
a
x
q
)
n| (ax_p-ax_q)
n∣(axp−axq) ,因为
a
a
a 和
n
n
n 互质,
(
x
p
−
x
q
)
<
n
(x_p-x_q)<n
(xp−xq)<n,所以
n
n
n 不可能整除
a
x
p
−
a
x
q
ax_p-ax_q
axp−axq ,所以不存在两个数同余,证毕。
推论二:
M
M
M 中的数模
n
n
n 的余数
(
a
x
i
m
o
d
n
)
(ax_i \ mod \ n)
(axi mod n) 全部与
n
n
n 互质
证明:
a
a
a 与
n
n
n 互质,
x
i
x_i
xi 与
n
n
n 互质,所以可得
a
x
i
ax_i
axi 与
n
n
n 互质,带入到欧几里得算法中:
g
c
d
(
a
x
i
,
n
)
=
g
c
d
(
n
,
a
x
i
m
o
d
n
)
=
1
gcd(ax_i,n)=gcd(n,ax_i \ mod \ n)=1
gcd(axi,n)=gcd(n,axi mod n)=1 ,证毕。
根据以上两个推论,就可以进行推式子了。根据推论知道,
M
M
M 中的任意两个数模
n
n
n 不同余且与
n
n
n 互质,
x
1
,
x
2
,
x
3
…
…
x
φ
(
n
)
x_1,x_2,x_3……x_{\varphi(n)}
x1,x2,x3……xφ(n) 也与
n
n
n 互质,模
n
n
n 不同余,那么它们模
n
n
n 的余数是相互对应的,可以得到:
a
x
1
×
a
x
2
×
a
x
3
…
…
×
a
x
φ
(
n
)
≡
x
1
×
x
2
×
x
3
×
…
…
×
x
φ
(
n
)
(
m
o
d
n
)
ax_1\times ax_2\times ax_3……\times ax_{\varphi(n)}≡x_1\times x_2\times x_3\times ……\times x_{\varphi(n)} (mod \ n)
ax1×ax2×ax3……×axφ(n)≡x1×x2×x3×……×xφ(n)(mod n)
则:
a
φ
(
n
)
(
x
1
×
x
2
×
x
3
×
…
…
×
x
φ
(
n
)
)
≡
x
1
×
x
2
×
x
3
×
…
…
×
x
φ
(
n
)
(
m
o
d
n
)
a^{\varphi(n)}(x_1\times x_2\times x_3\times ……\times x_{\varphi(n)}) ≡x_1\times x_2\times x_3\times ……\times x_{\varphi(n)} (mod \ n)
aφ(n)(x1×x2×x3×……×xφ(n))≡x1×x2×x3×……×xφ(n)(mod n)
移项可得:
(
a
φ
(
n
)
−
1
)
(
x
1
×
x
2
×
x
3
×
…
…
×
x
φ
(
n
)
)
≡
0
(
m
o
d
n
)
(a^{\varphi(n)}-1)(x_1\times x_2\times x_3\times ……\times x_{\varphi(n)}) ≡0 (mod \ n)
(aφ(n)−1)(x1×x2×x3×……×xφ(n))≡0(mod n)
所以
a
φ
(
n
)
≡
1
(
m
o
d
n
)
a^{\varphi(n)}≡1(mod \ n)
aφ(n)≡1(mod n)。
(2)费马小定理
若
p
p
p 是质数,对于任意整数
a
a
a ,则:
a
p
≡
a
(
m
o
d
p
)
a^p≡a(mod \ p)
ap≡a(mod p) 。
证明:
可用欧拉定理定理证明,若 a , p a,p a,p 互质, a φ ( p ) ≡ 1 ( m o d p ) a^{φ(p)}≡1(mod \ p) aφ(p)≡1(mod p) ,质数 p p p 的欧拉函数 φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p−1,所以 a p − 1 ≡ 1 ( m o d p ) a^{p-1}≡1(mod \ p) ap−1≡1(mod p),两边同时乘以 a a a ,则 a p ≡ a ( m o d p ) a^p≡a(mod p) ap≡a(modp) ;若 a , p a,p a,p 不互质,因为 p p p 是质数,则 a a a 一定是 p p p 的倍数, a p ≡ a ≡ 0 ( m o d p ) a^p≡a≡0(mod \ p) ap≡a≡0(mod p)。其实,费马小定理算是欧拉定理的一个特例。
(3)欧拉定理的推论
若正整数
a
,
n
a,n
a,n 互质,那么对于任意正整数
b
b
b ,有:
a
b
≡
a
b
m
o
d
φ
(
n
)
(
m
o
d
n
)
a^b≡a^{b \ mod \ φ(n)}(mod \ n)
ab≡ab mod φ(n)(mod n) 。
证明:
设
b
=
q
×
φ
(
n
)
+
r
b=q\times φ(n)+r
b=q×φ(n)+r,其中
0
≤
r
<
φ
(
n
)
0\leq r<φ(n)
0≤r<φ(n) ,即
r
=
b
m
o
d
φ
(
n
)
r=b \ mod \ φ(n)
r=b mod φ(n)。
于是
a
b
≡
a
q
×
φ
(
n
)
+
r
≡
(
a
φ
(
n
)
)
q
×
a
r
≡
1
q
×
a
r
≡
a
b
m
o
d
φ
(
n
)
(
m
o
d
n
)
a^b ≡ a^{q\times φ(n)+r}≡(a^{φ(n)})^q\times a^r≡1^q\times a^r≡a^{b \ mod \ φ(n)}(mod \ n )
ab≡aq×φ(n)+r≡(aφ(n))q×ar≡1q×ar≡ab mod φ(n)(mod n) 。
许多计数类的题目要求把答案对一个质数 P P P 取模,可以先将底数对 P P P 取模,指数对 $ φ§ (φ§=P-1)$取模,将计算的规模缩小。
特别的,当 a , n a,n a,n 不一定互质且 b > φ ( n ) b> φ(n) b>φ(n) 时,有 a b ≡ a b m o d φ ( n ) + φ ( n ) ( m o d n ) a^b≡a^{b \ mod \ φ(n)+φ(n)}(mod \ n) ab≡ab mod φ(n)+φ(n)(mod n),可自行证明。
3. 同余性质
对于整数
a
,
b
,
c
,
d
a,b,c,d
a,b,c,d 和自然数
m
m
m ,对模
m
m
m 同余满足:
(1)对称性:若
a
≡
b
(
m
o
d
m
)
a≡b(mod\ m)
a≡b(mod m) ,则
b
≡
a
(
m
o
d
m
)
b≡a(mod \ m)
b≡a(mod m) 。
(2)传递性:若
a
≡
b
(
m
o
d
m
)
a≡b(mod \ m)
a≡b(mod m) ,
b
≡
c
(
m
o
d
m
)
b≡c(mod \ m)
b≡c(mod m) ,则
a
≡
c
(
m
o
d
m
)
a≡c(mod \ m)
a≡c(mod m) 。
(3)同加性:若
a
≡
b
(
m
o
d
m
)
a≡b(mod \ m)
a≡b(mod m) ,则
a
+
c
≡
b
+
c
(
m
o
d
m
)
a+c≡b+c(mod \ m)
a+c≡b+c(mod m) 。
(4)同乘性:若
a
≡
b
(
m
o
d
m
)
a≡b(mod \ m)
a≡b(mod m) ,则
a
c
≡
b
c
(
m
o
d
m
)
ac≡bc(mod \ m)
ac≡bc(mod m)。
a
≡
b
(
m
o
d
m
)
a≡b(mod \ m)
a≡b(mod m) ,
c
≡
d
(
m
o
d
m
)
c≡d(mod \ m)
c≡d(mod m) ,则
a
c
≡
b
d
(
m
o
d
m
)
ac≡bd(mod \ m)
ac≡bd(mod m)。
(5)同幂性: 若
a
≡
b
(
m
o
d
m
)
a≡b(mod\ m)
a≡b(mod m),则
a
c
≡
b
c
(
m
o
d
m
)
ac≡bc(mod \ m)
ac≡bc(mod m)。
注意,同余不满足同除性,即不满足,若
a
≡
b
(
m
o
d
m
)
a≡b(mod\ m)
a≡b(mod m) ,则
a
c
≡
b
c
(
m
o
d
m
)
\frac a c≡\frac b c(mod \ m)
ca≡cb(mod m) 。
4.扩展欧几里得算法
裴蜀定理
对于任意自然数 a , b a,b a,b ,存在整数 x , y x,y x,y 满足 a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b) 。
证明:
当 b = 0 b=0 b=0 时,存在一组整数解 x = 1 , y = 0 x=1,y=0 x=1,y=0 ,使得 a × 1 + b × 0 = g c d ( a , 0 ) = a a\times 1+b\times 0=gcd(a,0)=a a×1+b×0=gcd(a,0)=a 。
当 b ≠ 0 b \not =0 b=0 时, 根据欧几里得算法,求解 g c d ( a , b ) gcd(a,b) gcd(a,b) ,可以递归求解 g c d ( b , a % b ) gcd(b,a\ \% \ b) gcd(b,a % b) ,带入到方程 a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b) 。
假设存在一组解 x 1 , y 1 x_1,y_1 x1,y1 ,满足 b x 1 + ( a % b ) y 1 = g c d ( b , a % b ) = g c d ( a , b ) bx_1+(a \%b)y_1=gcd(b,a\%b)=gcd(a,b) bx1+(a%b)y1=gcd(b,a%b)=gcd(a,b),
展开后为: b x 1 + ( a − a b × b ) y 1 = g c d ( b , a % b ) bx_1+(a-\frac a b\times b)y_1=gcd(b,a\%b) bx1+(a−ba×b)y1=gcd(b,a%b) ,此处的 a b \frac a b ba 为整除。合并后有: a y 1 + b ( x 1 − a b × y 1 ) = g c d ( b , a % b ) ay_1+b(x_1-\frac a b \times y_1)=gcd(b,a\%b) ay1+b(x1−ba×y1)=gcd(b,a%b) 。
a x + b y = g c d ( a , b ) ax + by = gcd(a,b) ax+by=gcd(a,b)
a y 1 + b ( x 1 − a b × y 1 ) = g c d ( b , a % b ) ay_1+b(x_1-\frac a b \times y_1)=gcd(b,a\%b) ay1+b(x1−ba×y1)=gcd(b,a%b)
g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\ \% \ b) gcd(a,b)=gcd(b,a % b)
由以上三个式子可以得到: x = y 1 , y = x 1 − a b × y 1 x=y_1,y=x_1-\frac a b \times y_1 x=y1,y=x1−ba×y1 。
因此,求解 x , y x,y x,y,可以通过 x 1 , y 1 x_1,y_1 x1,y1 求解。欧几里得算法本身就是递归的过程, x 1 , y 1 x_1,y_1 x1,y1 可以通过 x 2 , y 2 x_2,y_2 x2,y2 求解…,递归边界为 b = 0 b=0 b=0 , 此时存在解为 x i = 1 , y i = 0 x_i=1,y_i=0 xi=1,yi=0,递归返回时则可以依次求解,最后得到 x , y x,y x,y 的解。
裴蜀定理是按欧几里得算法证明的,同时给出了解的计算方法,这种方法称为扩展欧几里得算法。求得的解为一组特解,存在多组解。
【参考程序】
int exgcd( int a, int b, int &x, int &y) //扩展欧几里得算法,&为引用
{ if (b==0) { x=1; y=0; return a; }
int d=exgcd( b, a%b, x, y);
int t=x; //递归返回,此时x,y保存的为下一层的值
x=y; //更新当前层新的x
y=t-a/d*y; //更新当前层新的y
return d; //可以同时求解最大公约数
}
5. 扩展欧几里得算法的应用
(1)求解不定方程 a x + b y = c ax+by=c ax+by=c
对于不定方程 a x + b y = c ax+by=c ax+by=c,当且仅当 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c 时,方程有整数解。
设 d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b),通过扩展欧几里得算法可以求得: a x 1 + b y 1 = d ax_1+by_1=d ax1+by1=d 的一组特解: x 1 , y 1 x_1,y_1 x1,y1 。
方程两边同时乘以 c d \frac c d dc ,可以得到不定方程 a x + b y = c ax+by=c ax+by=c 的一组特解: x = c d x 1 , y = c d y 1 x=\frac c d x_1 , y=\frac c d y_1 x=dcx1,y=dcy1 。
不定方程 a x + b y = c ax+by=c ax+by=c 通解可以表示为:
x = c d x 1 + t b d , y = c d y 1 − t a d x=\frac c dx_1 +t \frac b d ,y=\frac c d y_1-t\frac a d x=dcx1+tdb,y=dcy1−tda ( t t t 为整数),可以将通解带入到方程中进行验证。
当不满足 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c 时,无解。
通常题目要求最小正整数解,如果特解为 x x x ,则最小正整数解 = ( ( x % b d ) + b d ) % b d =((x\%\frac b d)+\frac b d)\%\frac b d =((x%db)+db)%db,因为求出的特解可能为负数,需要加 b d \frac b d db ,如果不是负数,则还需要模一次。 y y y 的求解方法类似。
【例1】青蛙的约会(POJ 1061)
【问题描述】
两只青蛙住在同一条纬度线上,于是它们约定各自朝对方跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。
我们把这两只青蛙分别叫做青蛙 A A A 和青蛙 B B B ,并且规定纬度线上东经 0 0 0 度处为原点,由东往西为正方向,单位长度 1 1 1 米,这样我们就得到了一条首尾相接的数轴。设青蛙 A A A 的出发点坐标是 x x x ,青蛙 B B B 的出发点坐标是 y y y 。青蛙 A A A 一次能跳 m m m 米,青蛙 B B B 一次能跳 n n n米,两只青蛙跳一次所花费的时间相同。纬度线总长 L L L 米。现在要你求出它们跳了几次以后才会碰面。
【输入格式】
输入只包括一行 5 5 5 个整数 x , y , m , n , L x,y,m,n,L x,y,m,n,L,其中 x ≠ y < 2000000000 , 0 < m 、 n < 2000000000 , 0 < L < 2100000000 x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000 x=y<2000000000,0<m、n<2000000000,0<L<2100000000。
【输出格式】
输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行 " I m p o s s i b l e " "Impossible" "Impossible" 。
【样例输入】
1 2 3 4 5
【样例输出】
4
【算法分析】
设一共跳了 T T T 步,则青蛙 A A A 最后的位置在 ( x + m T ) m o d L (x+mT)\ mod \ L (x+mT) mod L ,青蛙 B B B 最后的位置在 ( y + n T ) m o d L (y+nT)\ mod \ L (y+nT) mod L ,青蛙 A A A 和青蛙 B B B 相遇,则 x + m T ≡ y + n T ( m o d L ) x+mT≡y+nT(\ mod \ L) x+mT≡y+nT( mod L) ,可得到不定方程: ( x + m T ) + k L = y + n T (x+mT)+kL=y+nT (x+mT)+kL=y+nT , k k k 为整数。(转换方法参考同余,定理2)
移项可得: ( n − m ) T + k L = x − y (n-m)T+kL=x-y (n−m)T+kL=x−y,其中 T , k T,k T,k 是整数且未知。这就是标准的不定方程。
题目要求求最小的正整数解 T T T 。
【参考程序】
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll x,y,n,m,L;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b==0) {x=1;y=0;return a;}
ll d=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-a/b*y;
return d;
}
int main()
{
ll a,b,d;
cin>>x>>y>>m>>n>>L;
if(n<m) {swap(m,n);swap(x,y);} //保证n-m>0
d=exgcd(n-m,L,a,b); //特解为a,b,原方程特解为a*(x-y)/d
if((x-y)%d!=0||m==n) cout<<"Impossible\n";
else
cout<<((a*(x-y)/d)%(L/d)+(L/d))%(L/d) <<endl;
return 0;
}
(2)求解线性同余方程 a x ≡ b ( m o d m ) ax≡b(\ mod \ m) ax≡b( mod m)
给定整数 a , b , m a,b,m a,b,m ,求一个整数 x x x 满足 a x ≡ b ( m o d m ) ax≡b(\ mod\ m) ax≡b( mod m) ,或者给出无解。因为未知指数为 1 1 1 ,所有称为一次同余方程,也称线性同余方程。
a x ≡ b ( m o d m ) ax≡b(\ mod\ m) ax≡b( mod m) 等价于 a x − b ax-b ax−b 是 m m m 的倍数,不妨设为 − y -y −y 倍。于是,该方程可以改写为: a x + m y = b ax+my=b ax+my=b 。
按照扩展欧几里得算法求解方程 a x + m y = b ax+my=b ax+my=b 即可。
【例2】同余方程(NOIP 2012 提高)
【问题描述】
求关于 x x x 同余方程 a x ≡ 1 ( m o d b ) ax ≡ 1 (\ mod \ b) ax≡1( mod b) 的最小正整数解。
【输入格式】
输入只有一行,包含两个正整数 a , b a, b a,b,用 一个 空格隔开。
【输出格式】
输出只有一行包含一个正整数 x 0 x_0 x0,即最小正整数解,输入数据保证一定有解。
【样例输入】
3 10
【样例输出】
7
【数据范围】
对于 40 % 40\% 40% 的数据, 2 ≤ b ≤ 1 , 000 2 ≤b≤ 1,000 2≤b≤1,000 ;
对于 60 % 60\% 60% 的数据, 2 ≤ b ≤ 50 , 000 , 000 2 ≤b≤ 50,000,000 2≤b≤50,000,000
对于 100 % 100\% 100% 的数据, 2 ≤ a , b ≤ 2 , 000 , 000 , 000 2 ≤a, b≤ 2,000,000,000 2≤a,b≤2,000,000,000
【算法分析】
同余方程 a x ≡ 1 ( m o d b ) ax ≡ 1 (\ mod \ b) ax≡1( mod b) 可改写为 a x + b y = 1 ax+by=1 ax+by=1 ,使用扩展欧几里得算法求解。
(3)乘法逆元
若整数 a , p a,p a,p 互质, g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1 , a x ≡ 1 ( m o d p ) ax≡1(mod \ p) ax≡1(mod p) ,称 a a a 关于模 p p p 的乘法逆元为 x x x 。如 4 x ≡ 1 ( m o d 5 ) 4x≡1(mod \ 5) 4x≡1(mod 5), ( 4 × 9 ) % 5 = 1 (4\times 9)\%5=1 (4×9)%5=1,$9 $ 为 4 4 4 模 5 5 5 的乘法逆元。
有了乘法逆元,就能解决除法取模的问题了。
求解 a b % p \frac a b \%p ba%p( p p p 为质数),因为 a b ≡ a b ( m o d p ) \frac a b ≡\frac a b(\ mod \ p) ba≡ba( mod p), b x ≡ 1 ( m o d p ) bx≡1(mod \ p) bx≡1(mod p) ( x x x 为 b b b 模 p p p 的乘法逆元),所以: a b × b x ≡ a b × 1 ( m o d p ) \frac a b \times bx≡\frac a b \times 1(mod \ p) ba×bx≡ba×1(mod p) 。
即: a x ≡ a b ( m o d p ) ax≡\frac a b (mod \ p) ax≡ba(mod p)
因此,对于 a a a 除以 b b b 取模,等价于 a a a 乘以 b b b 模 p p p 的乘法逆元再取模。就可以分别计算 a % p a\%p a%p , x % p x\%p x%p ,最后相乘再 % p \%p %p 。前提是 b , p b,p b,p 互质。
乘法逆元可以通过费马小定理和扩展欧几里得算法求解。
费马小定理
若 p p p 是质数,对于任意整数 a a a ,则: a p ≡ a ( m o d p ) a^p≡a(mod \ p) ap≡a(mod p),那么 a ( a p − 1 − 1 ) ≡ 0 ( m o d p ) a(a^{p-1}-1)≡0(mod \ p) a(ap−1−1)≡0(mod p),即 a p − 1 ≡ 1 ( m o d p ) a^{p-1}≡1(mod \ p) ap−1≡1(mod p),那么 a × a p − 2 ≡ 1 ( m o d p ) a\times a^{p-2}≡1(mod \ p) a×ap−2≡1(mod p) , a p − 2 a^{p-2} ap−2 就是 a a a 模 p p p 的乘法逆元。
扩展欧几里得算法
a x ≡ 1 ( m o d p ) ax≡1(mod \ p) ax≡1(mod p) 的解其实就相当于寻找方程 a ∗ x + p ∗ y = 1 a*x+p*y=1 a∗x+p∗y=1 的解,而 a , p a,p a,p 互质, g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1 ,刚好就是扩展欧几里得算法的标准形式。
【例3】Sumdiv(POJ 1845)
【问题描述】
给定两个自然数 A A A 和 B B B , S S S 为 A B A^B AB 的所有正整数约数和,编程输出 S m o d 9901 S \ mod \ 9901 S mod 9901 的结果。
【输入格式】
只有一行,两个用空格隔开的自然数 A A A 和 B B B ( 0 ≤ A , B ≤ 50000000 ) (0\leq A,B\leq 50000000) (0≤A,B≤50000000)。
【输出格式】
只有一行,即 S m o d 9901 S \ mod \ 9901 S mod 9901 的结果。
【样例输入】
2 3
【样例输出】
15
【算法分析】
根据唯一分解定理,任何一个大于 1 1 1 的自然数都能分解成有限个质数相乘的形式,即 A B = p 1 a 1 × B × p 2 a 2 × B × . . . × p k a k × B A^B=p_1^{a_1\times B}\times p_2^{a_2\times B} \times ... \times p_k^{a_k\times B} AB=p1a1×B×p2a2×B×...×pkak×B 。所以 A B A^B AB 的所有约数和 s u m = ( 1 + p 1 + p 1 2 + . . . + p 1 a 1 × B ) × ( 1 + p 2 + p 2 2 + . . . + p 2 a 2 × B ) × . . . × ( 1 + p k + p k 2 + . . . + p k a k × B ) sum=(1+p_1+p_1^2+...+p_1^{a_1\times B})\times (1+p_2+p_2^2+...+p_2^{a_2\times B})\times ...\times (1+p_k+p_k^2+...+p_k^{a_k\times B}) sum=(1+p1+p12+...+p1a1×B)×(1+p2+p22+...+p2a2×B)×...×(1+pk+pk2+...+pkak×B) 。
方法一:快速幂+乘法逆元
对于每一个 ( 1 + p i + p i 2 + . . . + p i a i ) (1+p_i+p_i^2+...+p_i^{a_i}) (1+pi+pi2+...+piai) ,这是一个标准的等比数列,根据等比数列求和公式,可以得出和为 p i a i + 1 − 1 p i − 1 \frac {p_i^{a_i+1}-1} {p_i-1} pi−1piai+1−1 ,再 m o d 9901 \ mod \ 9901 mod 9901 。分子可以使用快速幂求解,分子除以分母取模,转换为分子乘以分母的乘法逆元取模。
使用乘法逆元时,需要满足 p i − 1 p_i-1 pi−1 与 9901 9901 9901 互质,因为 9901 9901 9901 是质数,只可能存在 p i − 1 p_i-1 pi−1 是 9901 9901 9901 的倍数,此时不能使用乘法逆元,但是可以知道 p i m o d 9901 = 1 p_i \ mod \ 9901=1 pi mod 9901=1 ,则等比数列可以直接求解: ( 1 + p i + p i 2 + . . . + p i a i ) m o d 9901 = 1 + 1 + 1... + 1 = a i + 1 (1+p_i+p_i^2+...+p_i^{a_i}) \ mod \ 9901=1+1+1...+1=a_i+1 (1+pi+pi2+...+piai) mod 9901=1+1+1...+1=ai+1 。
方法二:分治
对于等比数列 ( 1 + p i + p i 2 + . . . + p i a i ) (1+p_i+p_i^2+...+p_i^{a_i}) (1+pi+pi2+...+piai) ,
当 a i a_i ai 为奇数时, 1 + p i + p i 2 + . . . + p i a i = ( 1 + p a i 2 + 1 ) × ( 1 + p i + . . . + p i a i 2 ) 1+p_i+p_i^2+...+p_i^{a_i}=(1+p^{\frac {a_i} 2 +1})\times (1+p_i+...+p_i^{\frac {a_i} 2}) 1+pi+pi2+...+piai=(1+p2ai+1)×(1+pi+...+pi2ai)
展开后就有: ( 1 + p i + . . . + p i a i 2 ) + ( p a i 2 + 1 + p a i 2 + 2 + p a i 2 + 1 + . . . + p a i ) (1+p_i+...+p_i^{\frac {a_i} 2})+(p^{\frac {a_i} 2 +1}+p^{\frac {a_i} 2 +2}+p^{\frac {a_i} 2 +1}+...+p^{a_i }) (1+pi+...+pi2ai)+(p2ai+1+p2ai+2+p2ai+1+...+pai),因为 a i a_i ai 为奇数,所以 p i a i 2 + a i 2 + 1 = p i a i p_i^{\frac {a_i} 2+\frac {a_i} 2+1}=p_i^{a_i} pi2ai+2ai+1=piai .
当 a i a_i ai 为偶数时, 1 + p i + p i 2 + . . . + p i a i = ( 1 + p a i 2 ) × ( 1 + p i + . . . + p i a i 2 ) 1+p_i+p_i^2+...+p_i^{a_i}=(1+p^{\frac {a_i} 2})\times (1+p_i+...+p_i^{\frac {a_i} 2}) 1+pi+pi2+...+piai=(1+p2ai)×(1+pi+...+pi2ai)
可以通过分治的方法,递归求解等比数列。
因此,等比数列求和可以使用快速幂+乘法逆元的方法,也可以使用分治的方法。