0x33 同余

0x33 同余

定义

若整数 a a a和整数 b b b除以正整数 m m m的余数相等,则称 a , b a,b a,b m m m同余,记为 a ≡ b ( m o d   m ) a\equiv b(mod\ m) ab(mod m)

同余类与剩余类

对于 ∀ a ∈ [ 0 , m − 1 ] \forall a\in[0,m-1] a[0,m1],集合 { a + k m } ( k ∈ Z ) \{a+km\}(k\in Z) {a+km}(kZ)的所有数模 m m m同余,余数都是 a a a。该集合称为一个模 m m m同余类,简记为 a ‾ \overline{a} a

m m m的同余类一共有 m m m个,分别为 0 ‾ , 1 ‾ , 2 ‾ , . . . , m − 1 ‾ \overline0,\overline1,\overline2,...,\overline{m-1} 0,1,2,...,m1。它们构成 m m m完全剩余类

1 ∼ m 1\sim m 1m中与 m m m互质的数代表的同余类共有 ϕ ( m ) \phi(m) ϕ(m)个,它们构成 m m m简化剩余类。例如,模10的简化剩余类为 { 1 ‾ , 3 ‾ , 7 ‾ , 9 ‾ } \{\overline1,\overline3,\overline7,\overline9 \} {1,3,7,9}

简化剩余关系关于模 m m m乘法封闭。这是因为若 a , b ( 1 ≤ a , b ≤ m ) a,b(1\leq a,b \leq m) a,b(1a,bm) m m m互质,则 a ∗ b a*b ab也不可能与 m m m含有相同的因子,即 a ∗ b a*b ab也与 m m m互质。再由余数的定义即可得到 a ∗ b   m o d   m a*b\bmod m abmodm也与 m m m互质, a ∗ b   m o d   m a*b\bmod m abmodm也属于 m m m的简化剩余类。

费马小定理

p p p是质数,则对于任意整数 a a a,有 a p ≡ a (   m o d   p ) a^p\equiv a(\bmod p) apa(modp)

欧拉定理

若正整数 a , n a,n a,n互质,则 a ϕ ( n ) ≡ 1 (   m o d   n ) a^{\phi(n)}\equiv 1(\bmod n) aϕ(n)1(modn),其中 ϕ ( n ) \phi(n) ϕ(n)为欧拉函数。

证明:
n n n的简化剩余类为 a 1 ‾ , a 2 ‾ , . . . , a ϕ ( n ) ‾ {\overline{a_1},\overline{a_2},...,\overline{a_{\phi(n)}}} a1,a2,...,aϕ(n)。对于 ∀ a i , a j \forall a_i,a_j ai,aj,若 a ∗ a i ≡ a ∗ a j (   m o d   n ) a*a_i\equiv a*a_j(\bmod n) aaiaaj(modn),则 a ∗ ( a i − a j ) ≡ 0 a*(a_i-a_j)\equiv 0 a(aiaj)0。因为 a , n a,n a,n互质,所以 a i − a j ≡ 0 a_i-a_j\equiv 0 aiaj0,即当 a i ≡ a j a_i\equiv a_j aiaj。故当 a i ≠ a j a_i\neq a_j ai=aj时, a a i , a a j aa_i,aa_j aai,aaj也代表不同的同余类。

又因为简化剩余系关于模 n n n乘法封闭,故 a a i ‾ \overline{aa_i} aai也在简化剩余系集合中。因此,集合 { a 1 ‾ , a 2 ‾ , . . . , a ϕ ( n ) ‾ } \{\overline{a_1},\overline{a_2},...,\overline{a_{\phi(n)}} \} {a1,a2,...,aϕ(n)}与集合 { a a 1 ‾ , a a 2 ‾ , . . . , a a ϕ ( n ) ‾ } \{\overline{aa_1},\overline{aa_2},...,\overline{aa_{\phi(n)}} \} {aa1,aa2,...,aaϕ(n)}都能表示 n n n的简化剩余类。综上所述:
a ϕ ( n ) a 1 a 2 . . . a ϕ ( n ) ≡ ( a a 1 ) ( a a 2 ) . . . ( a a ϕ ( n ) ) ≡ a 1 a 2 . . . a ϕ ( n ) (   m o d   n ) a^{\phi(n)}a_1a_2...a_{\phi(n)}\equiv (aa_1)(aa_2)...(aa_{\phi(n)})\equiv a_1a_2...a_{\phi(n)}(\bmod n) aϕ(n)a1a2...aϕ(n)(aa1)(aa2)...(aaϕ(n))a1a2...aϕ(n)(modn)
因此 a ϕ ( n ) ≡ 1 (   m o d   n ) a^{\phi(n)}\equiv 1(\bmod n) aϕ(n)1(modn)

p p p是质数时, ϕ ( p ) = p − 1 \phi(p)=p-1 ϕ(p)=p1,并且只有 p p p的倍数与 p p p不互质。所以,只要 a a a不是 p p p的倍数,就有 a p − 1 ≡ 1 (   m o d   p ) a^{p-1}\equiv 1(\bmod p) ap11(modp),两边同乘 a a a就是费马小定理。另外,若 a a a p p p的倍数,费马小定理显然成立(取模之后结果为0)。

欧拉定理的推论

设正整数 a , n a,n a,n互质,则对于任意正整数 b b b,有 a b ≡ a b   m o d   ϕ ( n ) (   m o d   n ) a^b\equiv a^{b\bmod \phi(n)}(\bmod n) ababmodϕ(n)(modn)

证明:

b = q ∗ ϕ ( n ) + r b=q*\phi(n)+r b=qϕ(n)+r,其中 0 ≤ r ≤ ϕ ( n ) 0\leq r\leq \phi(n) 0rϕ(n),即 r = b   m o d   ϕ ( n ) r=b\bmod \phi(n) r=bmodϕ(n)。于是:
a b ≡ a q ∗ ϕ ( n ) + r ≡ ( a ϕ ( n ) ) q ∗ a r ≡ a r ≡ a b   m o d   ϕ ( n ) (   m o d   n ) a^b\equiv a^{q*\phi(n)+r}\equiv(a^{\phi(n)})^q*a^r\equiv a^r\equiv a^{b\bmod \phi(n)}(\bmod n) abaqϕ(n)+r(aϕ(n))qararabmodϕ(n)(modn)
许多计数类的题目要求我们把答案对一个质数 p p p取模后输出。面对 a + b , a − b , a ∗ b a+b,a-b,a*b a+b,ab,ab这样的算式,可以在计算前先把 a , b a,b a,b p p p取模。面对乘方算式,根据欧拉定理的推论,可以先把底数对 p p p取模、指数对 ϕ ( p ) \phi(p) ϕ(p)取模,再计算乘方。

特别地, a , n a,n a,n不一定互质且 b > ϕ ( n ) b>\phi(n) b>ϕ(n)时,有 a b ≡ a b   m o d   ϕ ( n ) + ϕ ( n ) (   m o d   n ) a^b\equiv a^{b\bmod \phi(n)+\phi(n)}(\bmod n) ababmodϕ(n)+ϕ(n)(modn)这意味着即使底数与模数不互质,我们也有办法把指数地规模缩小到容易计算地范围内。上式可以通过寻找 a b   m o d   n a^b \bmod n abmodn指数循环节证明,可以自行思考。

1.扩展欧几里得算法

B e ˊ z o u t Bézout Beˊzout定理

对于任意整数 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*1+b*0=gcd(a,0) a1+b0=gcd(a,0)

b > 0 b>0 b>0,则 g c d ( a , b ) = g c d ( b , a   m o d   b ) gcd(a,b)=gcd(b,a\bmod b) gcd(a,b)=gcd(b,amodb)。假设存在一对整数 x , y x,y x,y,满足 b ∗ x + ( a   m o d   b ) ∗ y = g c d ( b , a   m o d   b ) b*x+(a\bmod b)*y=gcd(b,a\bmod b) bx+(amodb)y=gcd(b,amodb),因为 b x + ( a   m o d   b ) y = b x + ( a − b ⌊ a / b ⌋ ) y = a y + b ( x − ⌊ a / b ⌋ y ) bx+(a\bmod b)y=bx+(a-b\lfloor a/b \rfloor)y=ay+b(x-\lfloor a/b\rfloor y) bx+(amodb)y=bx+(aba/b⌋)y=ay+b(xa/by),所以令 x ′ = y , y ′ = x − ⌊ a / b ⌋ y x^{\prime}=y, y^{\prime}=x-\lfloor a / b\rfloor y x=y,y=xa/by,就得到了 a x ′ + b y ′ = g c d ( a , b ) ax^{\prime}+by^{\prime}=gcd(a,b) ax+by=gcd(a,b)

对于欧几里得算法的递归过程中应用数学归纳法,可知 B e ˊ z o u t Bézout Beˊzout定理成立。

B e ˊ z o u t Bézout Beˊzout定理是按照欧几里得算法的思路证明的,且上述证明方法同时给出了整数 x x x y y 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 z=x;x=y;y=z-y*(a/b);
    return d;
}

定义变量 d , x 0 , y 0 d,x_0,y_0 d,x0,y0,调用 d = e x g c d ( a , b , x 0 , y 0 ) d=exgcd(a,b,x0,y0) d=exgcd(a,b,x0,y0)。注意在上述代码中, x 0 , y 0 x_0,y_0 x0,y0是以引用的方式传递的。上述程序求出方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解 x 0 , y 0 x_0,y_0 x0,y0,并返回 a , b a,b a,b的最大公约数 d d d

对于更为一般的方程 a x + b y = c ax+by=c ax+by=c,它有解当且仅当 d ∣ c d\mid c dc。我们可以先求出 a x + b y = d ax+by=d ax+by=d的一组特解 x 0 , y 0 x_0,y_0 x0,y0,然后令 x 0 , y 0 x_0,y_0 x0,y0同时乘上 c / d c/d c/d,就得到了 a x + b y = c ax+by=c ax+by=c的一组特解 ( c / d ) x 0 , ( c / d ) y 0 (c/d)x_0,(c/d)y_0 (c/d)x0,(c/d)y0

事实上,方程 a x + b y = c ax+by=c ax+by=c的通解可以表示为:
x = c d x 0 + k b d , y = c d y 0 − k a d ( k ∈ Z ) x=\frac{c}{d}x_0+k\frac{b}{d},y=\frac{c}{d}y_0-k\frac{a}{d}(k\in Z) x=dcx0+kdb,y=dcy0kda(kZ)
其中 k k k取遍整数集合, d = g c d ( a , b ) , x 0 , y 0 d=gcd(a,b),x_0,y_0 d=gcd(a,b),x0,y0 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组特解。

乘法逆元

若整数 b , m b,m b,m互质,并且 b ∣ a b\mid a ba,则存在一个整数 x x x,使得 a / b ≡ a ∗ x (   m o d   m ) a/b\equiv a*x(\bmod m) a/bax(modm)。称 x x x b b b的模 m m m乘法逆元,记为 b − 1 (   m o d   m ) b^{-1}(\bmod m) b1(modm)

因为 a / b ≡ a ∗ b − 1 ≡ a / b ∗ b ∗ b − 1 (   m o d   m ) a/b\equiv a*b^{-1}\equiv a/b*b*b^{-1}(\bmod m) a/bab1a/bbb1(modm),所以 b ∗ b − 1 ≡ 1 (   m o d   m ) b*b^{-1}\equiv 1(\bmod m) bb11(modm)

如果 m m m是质数(此时我们用符号 p p p代替 m m m),并且 b < p b<p b<p,根据费马小定理, b p − 1 ≡ 1 (   m o d   p ) b^{p-1}\equiv 1(\bmod p) bp11(modp),即 b ∗ b p − 2 ≡ 1 (   m o d   p ) b*b^{p-2}\equiv 1(\bmod p) bbp21(modp)。因此,当模数 p p p为质数时, b p − 2 b^{p-2} bp2即为 b b b的乘法逆元。

如果只是保证 b , m b,m b,m互质,那么乘法逆元可通过求解同余方程 b ∗ x ≡ 1 (   m o d   m ) b*x\equiv 1(\bmod m) bx1(modm)得到。下个部分我们就来介绍线性同余方程及其求解方法。

有了乘法逆元,我们在计数类问题中即使遇到 a / b a/b a/b这样的除法算式,也可以先把 a , b a,b a,b各自对模数 p p p取模,再计算 a ∗ b − 1   m o d   p a*b^{-1}\bmod p ab1modp作为最终的结果。当然,前提必须保证 b , p b,p b,p互质(当 p p p是质数时,等价于 b b b不是 p p p的倍数)。

到目前为止,我们在模 p p p运算下对加、减、乘、除、乘方运算都已经有了适当的处理方式。

2.线性同余方程

给定整数 a , b , m a,b,m a,b,m,求一个整数 x x x满足 a ∗ x ≡ b (   m o d   m ) a*x\equiv b(\bmod m) axb(modm),或者给出无解。因为未知数的指数为1,所以我们称之为一次同余方程,也称为线性同余方程。

a ∗ x ≡ b (   m o d   m ) a*x\equiv b(\bmod m) axb(modm)等价于 a ∗ x − b a*x-b axb m m m的倍数,不妨设为 − y -y y倍。于是,该方程可以改写为 a ∗ x + m ∗ y = b a*x+m*y=b ax+my=b

根据 B e ˊ z o u t Bézout Beˊzout定理及其证明过程,线性同余方程有解当且仅当 g c d ( a , m ) ∣ b gcd(a,m)\mid b gcd(a,m)b

在有解时,先用欧几里得算法求出一组整数 x 0 , y 0 x_0,y_0 x0,y0,满足 a ∗ x 0 + m ∗ y 0 = g c d ( a , m ) a*x_0+m*y_0=gcd(a,m) ax0+my0=gcd(a,m)。然后 x = x 0 ∗ b / g c d ( a , m ) x=x_0*b/gcd(a,m) x=x0b/gcd(a,m)就是原线性同余方程的一个解。

方程的通解则是所有模 m / g c d ( a , m ) m/gcd(a,m) m/gcd(a,m) x x x同余的整数。

由上述线性同余方程的知识可得, a ∗ x ≡ 1 (   m o d   b ) a*x\equiv 1(\bmod b) ax1(modb)有解当且仅当 g c d ( a , b ) = 1 gcd(a,b)=1 gcd(a,b)=1。方程可以改写为 a ∗ x + b ∗ y = 1 a*x+b*y=1 ax+by=1,用欧几里得算法求出一组特解 x 0 , y 0 x_0,y_0 x0,y0,则 x 0 x_0 x0就是原方程的一个解,通解为所有模 b b b x 0 x_0 x0同余的整数。通过取模操作把解的范围移动到 1 ∼ b 1\sim b 1b之间,就得到了最小正整数。

typedef long long ll;
ll a,b,x,y;
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(!b){x=1,y=0;return a;}
    ll d=exgcd(b,a%b,x,y);
    ll z=x;x=y;y=z-y*(a/b);
    return d;
}
int main()
{
    cin>>a>>b;
    exgcd(a,b,x,y);
    cout<<(x%b+b)%b<<endl; //注意通过同余方程求出的解可能为负数记得要加上一个b
}

中国剩余定理

m 1 , m 2 , . . . , m n m_1,m_2,...,m_n m1,m2,...,mn是两两互质的整数, m = ∏ i = 1 n m i , M i = m / m i , t i m=\prod_{i=1}^{n}m_i,M_i=m/m_i,t_i m=i=1nmi,Mi=m/mi,ti是线性同余方程 M i t i ≡ 1 (   m o d   m i ) M_it_i\equiv 1(\bmod m_i) Miti1(modmi)的一个解。对于任意的 n n n个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an,方程组
{ x ≡ a 1 (   m o d   m 1 ) x ≡ a 2 (   m o d   m 2 ) ⋮ x ≡ a n (   m o d   m n ) \left\{\begin{array}{c} x \equiv a_{1}\left(\bmod m_{1}\right) \\ x \equiv a_{2}\left(\bmod m_{2}\right) \\ \vdots \\ x \equiv a_{n}\left(\bmod m_{n}\right) \end{array}\right. xa1(modm1)xa2(modm2)xan(modmn)
有整数解,解为 x = ∑ i = 1 n a i M i t i x=\sum_{i=1}^n a_iM_it_i x=i=1naiMiti

证明:
因为 M i = m / m i M_i=m/m_i Mi=m/mi是除 m i m_i mi之外所有模数的倍数,所以 ∀ k ≠ i , a i M i t i ≡ 0 (   m o d   m k ) \forall k\neq i,a_iM_it_i\equiv 0(\bmod m_k) k=i,aiMiti0(modmk)。又因为 a i M i t i ≡ a i (   m o d   m i ) a_iM_it_i\equiv a_i(\bmod m_i) aiMitiai(modmi),所以代入 x = ∑ i = 1 n a i M i t i x=\sum_{i=1}^n a_iM_it_i x=i=1naiMiti,原方程组成立。

另外,即使模数不满足两两互质,我们也有方法判断线性同余方程组是否有解,并求出方程组的解。可以考虑使用数学归纳法,假设已经求出了前 k − 1 k-1 k1个方程构成的方程组的一个解 x x x。记 m = l c m ( m 1 , m 2 , . . . , m k − 1 ) m=lcm(m_1,m_2,...,m_{k-1}) m=lcm(m1,m2,...,mk1),则 x + i ∗ m ( i ∈ Z ) x+i*m(i\in Z) x+im(iZ)是前 k − 1 k-1 k1个方程的通解。

考虑第 k k k个方程,求出一个整数 t t t,使得 x + t ∗ m ≡ a k (   m o d   m k ) x+t*m\equiv a_k(\bmod m_k) x+tmak(modmk)。该方程等价于 m ∗ t ≡ a k − x (   m o d   m k ) m*t\equiv a_k-x(\bmod m_k) mtakx(modmk),其中 t t t是未知量。这就是一个线性同余方程,可以用扩展欧几里得算法判断是否有解,并求出它的解。若有解,则 x ′ = x + t ∗ m x^{\prime}=x+t*m x=x+tm就是前 k k k个方程构成的方程组的一个解。

综上所述,我们使用了 n n n次扩展欧几里得算法,就求出了整个方程组的解。

3.高次同余方程

关于高次同余方程,有 a x ≡ b (   m o d   p ) a^x\equiv b(\bmod p) axb(modp) x a ≡ b (   m o d   p ) x^a\equiv b(\bmod p) xab(modp)两类问题。不过后者超出了我们的讨论范围,可以自行查阅“原根”“阶”“指标”的相关资料。我们重点来解决前者。

问题:给定整数 a , b , p a,b,p a,b,p,其中 a , p a,p a,p互质,求一个非负整数 x x x,使得 a x ≡ b (   m o d   p ) a^x\equiv b(\bmod p) axb(modp)

Baby Step,Gaint Step算法

因为 a , p a,p a,p互质,所以可以在模 p p p意义下执行关于 a a a的乘、除法运算。

x = i ∗ t − j x=i*t-j x=itj,其中 t = ⌈ p ⌉ , 0 ≤ j ≤ t − 1 t=\lceil \sqrt{p} \rceil,0\leq j\leq t-1 t=p ,0jt1,则方程变为 a i ∗ t − j ≡ b (   m o d   p ) a^{i*t-j}\equiv b(\bmod p) aitjb(modp)。即 ( a t ) i ≡ b ∗ a j (   m o d   p ) (a^t)^i\equiv b*a^j(\bmod p) (at)ibaj(modp)

对于所有的 j ∈ [ 0 , t − 1 ] j\in[0,t-1] j[0,t1],把 b ∗ a j   m o d   p b*a^j\bmod p bajmodp插入一个Hash表。

枚举 i i i的所有可能取值,即 i ∈ [ 0 , t ] i\in[0,t] i[0,t],计算出 ( a t ) i   m o d   p (a^t)^i\bmod p (at)imodp,在Hash表中查找是否存在对应的 j j j,更新答案即可。时间复杂度 O ( p ) O(\sqrt{p}) O(p )

下面的程序实现了Baby Step,Gaint Step算法,计算同余方程 a x ≡ b (   m o d   p ) a^x\equiv b(\bmod p) axb(modp)最小非负整数解,无解时返回-1。

int baby_step_giant_step(int a,int b,int p)
{
    map<int,int> hash;hash.clear();
    b%=p;
    int t=(int)sqrt(p)+1;
    for(int j=0;j<t;++j)
    {
        int val=(long long)b*power(a,j,p)%p; //b*a^j
        hash[val]=j;
    }
    a=power(a,t,p); //a^t
    if(a==0) return b==0?1:-1;
    for(int i=0;i<=t;++i)
    {
        int val=power(a,i,p); //(a^t)^i;
        int j= hash.find(val)==hash.end()?-1:hash[val];
        if(j>=0&&i*t-j>=0) return i*t-j;
    }
    return -1;
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谷神星ceres

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值