同余
1. 模运算基本性质
基本概念
若整数 \(a,b\) 除以 \(p\) 的余数相等,则称 \(a,b\) 在模 \(p\) 意义下同余,记作 \(a \equiv b \pmod{p}\) 或者 \(a \bmod p=b \bmod p\)。
模运算的定义:
性质
-
\((a+b) \bmod p =(a \bmod p+b \bmod p)\bmod p\)。
-
\(ab \bmod p=(a\bmod p)(b \bmod p)\bmod p\)。
-
对于任意正整数 \(k\),有 $a \bmod p=(a \bmod kp)\bmod p $。
- Proof:考虑将 \(n\) 用 \(p,kp\) 表示,可得 \(n=xp+r_1=ykp+r_2\ (0\leq r_1<p,0\leq r_2 <kp)\)。继续将 \(r_2\) 用 \(p\) 表示,可得 \(r_2=zp+r_3\ (0\leq r_3<p)\)。命题得证。
-
若 \(k\mid a\),则有 \(\dfrac{a}{k} \bmod p=\dfrac{a \bmod kp}{k}\)。
- 由模运算的定义可得:\[\dfrac{a\bmod kp}{k}=\dfrac{1}{k}(a-kp\lfloor \dfrac{a}{kp}\rfloor)=\dfrac{a}{k}-p\lfloor\dfrac{a}{kp}\rfloor=\dfrac{a}{k}\bmod p \]
- 由模运算的定义可得:
-
\(ac\equiv bc \pmod{p}\Rightarrow a\equiv b\pmod{\dfrac{p}{\gcd(c,p)}}\)
-
Proof:设 \(\gcd(c,p)=d\),则有 \(c=k_1d,p=k_2d \,(k_1,k_2\in \mathbb{Z})\)。
左边式子移项可得 \(c(a-b)\equiv 0\pmod{p} \Rightarrow p\mid c(a-b)\Rightarrow k_2d \mid k_1d(a-b) \Rightarrow k_2 \mid k_1(a-b)\)。
由 \(\gcd\) 的定义得,\(k_1 \perp k_2\),则有 \(k_2 \mid (a-b)\Rightarrow \dfrac{p}{\gcd(c,p)}\mid (a-b)\)。
由此得 \(a\equiv b\pmod{\dfrac{p}{\gcd(c,p)}}\),命题得证。
-
2. 逆元
分数取模
对于 \(\dfrac{a}{b}\) 这样一个分数,对它进行模运算就会比较复杂。易得 \(\dfrac{a}{b}=a \cdot \dfrac{1}{b}\)。设 \(\dfrac{1}{b}\equiv x\pmod{p}\),则有 \(xb \equiv 1 \pmod{p}\)。找到这样一个最小的 \(x\),就会有 \(ax \equiv \dfrac{a}{b} \pmod{p}\)。\(x\) 就是下面提到的乘法逆元。
乘法逆元
设 \(a\) 为整数,\(x\) 为正整数,若
则称 \(x\) 为 \(a\) 在模 \(p\) 意义下的乘法逆元。
性质:当且仅当 \(a\perp p\) 时,\(a\) 在模 \(p\) 意义下的乘法逆元才存在。
- Proof:设 \(ax\equiv 1 \pmod{p}\)。假设 \(\gcd(a,p)=d>1\),则有 \(ax=k_1d,p=k_2d\)。由模运算的定义得:\[ax\bmod p=(k_1d) \bmod (k_2d)=k_1d-k_2d\lfloor \dfrac{k_1d}{k_2d}\rfloor=d(k_1-\lfloor\dfrac{k_1d}{k_2d}\rfloor) \]由于 \(d>1\),则 \(ax \bmod p\) 不可能等于 \(1\) ,假设不成立。
费马小定理
若 \(p\) 为质数,且 \(a\perp p\),则有:
Proof:
设数列 \(S_1=\{1,2,3\dots,p-1\}\),将 \(S_1\) 乘 \(a\) 得 \(S_2=\{a,2a,3a\dots,(p-1)a\}\)。
将两个数列同时 \(\bmod p\) 可得 \(S_1=\{1,2,3\dots,p-1\},S_2=\{a \bmod p,2a \bmod p,3a \bmod p\dots,(p-1)a \bmod p\}\)。
设 \(a \bmod p=x\),则 \(2a \bmod p=2x \bmod p\)。由于 \(p\) 为质数,\(2x \bmod p \ne x\Rightarrow a\bmod p \ne 2a \bmod p\)。
类似地,可得 \(3x \bmod p \ne x,3x \bmod p \ne 2x \bmod p\Rightarrow3a \bmod p\ne a \bmod p,3a \bmod p \ne 2a \bmod p\)。
以此类推,\(S_2\) 的元素间两两不等,且没有 \(0\) 出现,所以 \(S_1,S_2\) 在模 \(p\) 意义下都是 \(1\sim p-1\) 的排列。
设 \(S_1,S_2\) 中所有元素的连乘分别为 \(X,Y\),则有:
由此可得,\(a\) 在模 \(p\) 意义下的乘法逆元 \(x\) 即为 \(a^{p-2}\)。
线性求 \(1\sim n\) 的逆元:
方法1
对于 \(\dfrac{1}{i}\),用 \(i\) 来表示 \(p\):
由于 \(p \bmod i<i\),\(\dfrac{1}{p \bmod i}\) 在计算 \(\dfrac{1}{i}\) 之前就已经计算出来。
int n,p,inv[N];
void Solve(){
inv[1]=1;
for(int i=2;i<=n;i++)
inv[i]=1ll*(-p/i+p)*inv[p%i]%p;
}
注意出现负数时要加 \(p\)。
方法2:
预处理出 \(1\sim n\) 在模 \(p\) 意义下的阶乘数组,并利用费马小定理计算 \(\dfrac{1}{n!}\)。
利用 \(\dfrac{1}{i!}=\dfrac{1}{(i+1)!}(i+1)\),倒着推出所有的 \(\dfrac{1}{i!}\)。
从而利用 \(\dfrac{1}{i}=\dfrac{(i-1)!}{i!}\) 计算出所有的 \(\dfrac{1}{i}\)。
这个方法更加通用,因为预处理出的阶乘数组可以直接运用到组合计数中。
int n,p,fac[N],facv[N],inv[N];
int QuickPow(int a,int b){
int res=1;
while(b){
if(b&1) res=1ll*res*a%p;
b>>=1;
a=1ll*a*a%p;
}
return res;
}
void Solve(){
fac[0]=1; for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%p;
facv[n]=QuickPow(fac[n],p-2);
for(int i=n-1;i;i--) facv[i]=1ll*facv[i+1]*(i+1)%p;
for(int i=1;i<=n;i++) inv[i]=1ll*fac[i-1]*facv[i]%p;
}
3. 欧拉定理
同余类
对于 \(\forall a\in[0,m-1]\),集合 \({a+km}\ (k\in \mathbb{Z})\) 的所有数在模 \(m\) 意义下同余。
该集合称为一个模 \(m\) 的同余类,记为 \(\bar{a}\)。
剩余系
所有模 \(m\) 的 \(m-1\) 个同余类构成 \(m\) 的完全剩余系。
\(1\sim m\) 中与 \(m\) 互质的数字有 \(\phi(m)\) 个,它们代表的同余类构成 \(m\) 的简化剩余系。
\(m\) 的简化剩余系关于模 \(m\) 乘法封闭。
对于 \(\forall a,b\ (a,b\in[0,m-1]\land a\perp m \land b \perp m)\),\(ab\perp m\),也就是 \(\gcd(ab,m)=1\)。由辗转相除法得 \(\gcd(ab \bmod m,m)=\gcd(ab,m)=1\),故 \(ab \bmod m\) 代表的同余类也在 \(m\) 的简化剩余系中。
欧拉定理
若 \(a\perp n\),则有:
Proof:
设 \(n\) 的简化剩余系为 \(\{\overline{a_1},\overline{a_2},\overline{a_3}\dots,\overline{a_{\phi(n)}}\}\)。若存在 \(\forall a_i,a_j\) 满足 \(aa_i\equiv aa_j \pmod{n}\),则有 \(a_i\equiv a_j \pmod{n}\)。由此可得,当 \(a_i\not\equiv a_j\pmod{n}\) 时,\(aa_i \not\equiv aa_j\pmod{n}\)。
由于 \(n\) 的简化剩余系关于模 \(n\) 乘法封闭,故 \(\{\overline{a_1},\overline{a_2},\overline{a_3}\dots,\overline{a_{\phi(n)}}\}\) 与 \(\{\overline{aa_1},\overline{aa_2},\overline{aa_3}\dots,\overline{aa_{\phi(n)}}\}\)
都可以表示 \(n\) 的简化剩余系,则有:
命题得证。
由此可以从另一个角度证明费马小定理:当 \(p\) 为指数时,\(\phi(p)=p-1\),则有 \(a^{p-1}\equiv 1\pmod{p}\)。
Ex.1 The Luckiest Number
\(x\) 个 \(8\) 连在一起产生的数字可表示为 \(\dfrac{8}{9}(10^x-1)\),故题意转化为求一个最小正整数 \(x\),满足 。\(L\mid \dfrac{8}{9}(10^x-1)\)。
为了方便表述,不妨设 \(10^x-1=X\)。
设 \(\gcd(8,L)=d,8=k_1d,L=k_2d\)。
则有 \(9L \mid 8X \Rightarrow 8X \equiv 0 \pmod{9L} \Rightarrow \dfrac{8X}{d} \equiv 0 \pmod{\dfrac{9L}{d}} \Rightarrow k_1X \equiv 0 \pmod{9k_2}\)。
由于 \(k_1 \perp k_2\),则 \(k_1\) 在模 \(9k_2\) 意义下的乘法逆元存在,则有 \(X \equiv 0 \pmod{9k_2} \Rightarrow \dfrac{9L}{d} \mid X\)。
问题转化为求最小的 \(x\),使得 \(X \equiv 0 \pmod{\dfrac{9L}{d}}\),也就是 \(10^x \equiv 1 \pmod{\dfrac{9L}{d}}\)。
由于 \(\dfrac{9L}{d}\mid (10^x-1)\),故 \(\dfrac{9L}{d}\) 的正约数集合是 \(10^x-1\) 正约数集合的子集。 \(\gcd(10^x,10^x-1)=1\),\(10^x\) 与 \(10^x-1\) 没有公因子,所以 \(\dfrac{9L}{ d}\) 与 \(10^x\) 也没有公因子。
-
引理:若 \(a \perp p\),则使得 \(a^{x}\equiv 1 \pmod{p}\) 成立的最小 \(x\) 一定是 \(\phi(p)\) 的因子。
-
Proof:假设存在 \(x_0 \nmid \phi(p)\),满足 \(a^{x_0}\equiv 1 \pmod{p}\)。则有 \(a^{kx_0}\equiv 1 \pmod{p}\)。
令 \(\phi(p)=kx_0+r\ (r\in[0,x_0))\),可得:\(a^{\phi(p)} \equiv a^{kx_0+r} \equiv a^{kx_0}a^r \equiv a^r \equiv 1\pmod{p}\)。
与 "\(x_0\) 是使得条件成立的最小 \(x\)" 矛盾,命题得证。
故可以求出 \(\phi(\dfrac{9L}{d})\),再从小到大枚举其因子,即可找到答案。
4. 扩展欧拉定理
扩展到 \(a,n\) 不要求互质。
不难看出,\(1,3\) 两种情况可以归为一种。
前 \(2\) 种情况很显然,重点在第 \(3\) 种情况。(证明太难了,让我先咕一会) 。
Ex.2 上帝与集合的正确用法
求:
不妨设 \(f(x)=2^{2^{2^{2^{2\dots}}}} \bmod x\)。
由于 \(2^{2^{2^{2^{2\dots}}}}\) 一定大于 \(\phi(x)\),根据扩展欧拉定理可得:
这是一个递归的过程,显然不断给 \(x\) 赋值 \(\phi(x)\),结果一定会变为 \(1\)。
故递归边界为: 当 \(x=1\) 时,\(f(x)=0\)。
线性打出 \(1 \sim 10^7\) 的欧拉函数值后递归+快速幂求解即可。
5. 扩展欧几里得算法(Exgcd)
裴蜀定理
对于任意一组整数 \(a,b\),存在一组整数 \(x,y\),满足 \(ax+by=\gcd(a,b)\)。
Proof:
考虑数学归纳法。
当 \(b=0\) 时,由于 \(\gcd(a,0)=a\),则对于 \(ax+0y=a\) 这个不定方程,\(x=1\),\(y\) 取任意整数。
假设存在一组整数 \(x,y\),满足 $bx+(a\bmod b)y=\gcd(b,a\bmod b)=\gcd(a,b) $。
那么接下来证明也存在一组整数 \(x',y'\) 满足 \(ax'+by'=\gcd(a,b)\)。
当 \(x'=y,y'=x-\lfloor\dfrac{a}{b}\rfloor y\) 时满足条件。
那么利用辗转相除法进行递归,总能递归到 \(b=0\) 的情况。命题得证。
Exgcd
求关于 \(x,y\) 的方程 \(ax+by=c\) 的整数解。
设 \(d=\gcd(a,b)\),方程有整数解的充要条件是 \(d\mid c\)。
Proof:
设 \(a=k_1d,b=k_2d\),则有 \(k_1dx+k_2dy=c \Rightarrow k_1x+k_2y=\dfrac{c}{d}\)。
先证必要性: 由于 \(\dfrac{c}{d}\) 必须为整数,则 \(d \mid c\)。
再证充分性:上式中,\(k_1\perp k_2\),则方程 \(k_1x'+k_2y'=1\) 一定有整数解。由于 \(\dfrac{c}{d} \in\mathbb{Z}\),那么原方程也一定有整数解。
先将方程化简,两边同除以 \(d\)。此时 \(a,b\) 互质。
为了方便表述,下面提到的方程都是化简后的方程。
那么我们可以先利用裴蜀定理求出 \(ax'+by'=1\) 的一组特解 \(x',y'\),从而求出原方程的一组特解 \(x_0=cx’,y_0=cy'\)。
考虑如何求出通解。
让 \(x\) 加上一个数,那么 \(y\) 就要减去一个数。设这两个数为 \(\Delta_x,\Delta_y\),则有:
由于 \(a,b\) 互质,则 \(\dfrac{a}{b}\) 为最简整数比,则有 \(a \mid \Delta_y\) 且 \(\ b\mid \Delta_x\)。
由于 \(\Delta_x,\Delta_y \in \mathbb{Z}\),则 \(\Delta_x\) 最小取到 \(b\),\(\Delta_y\) 最小取到 \(a\)。
通解即为:
代回原方程,可以消掉 \(kb,ka\)。
接下来考虑,当存在正整数解时,如何求出最小正整数解与正整数解的个数。
对 \(x\) 的通解进行变形,求 \(x\) 的最小正整数解 \(x_1\):
先减一是为了避免 \(x_0 \bmod a\) 一开始就为 \(0\) 的情况,从而保证 \(x_1>0\)。
易得,当 \(x\) 增大时,\(y\) 减小。当 \(x\) 取 \(x_1\) 时,\(y\) 取到最大正整数解 \(y_2\)。
同理,求出 \(y\) 的最小正整数解 \(y_1\),当 \(y\) 取 \(y_1\) 时,\(x\) 取到最大正整数解 \(x_2\)。
由通解公式可得,\(x\) 每两个整数解之间相差 \(b\),\(y\) 每两个整数解之间相差 \(a\)。
正整数解的个数即为 \(\dfrac{x_2-x_1}{b}+1\)。
Ex.3 【模板】二元一次不定方程 (exgcd)
根据上面的分析,套用公式即可。
ll T,A,B,C,x,y,d,x1,x2,y1,y2,cnt;
ll GetX(ll Y){return (C-B*Y)/A;}
ll GetY(ll X){return (C-A*X)/B;}
ll Exgcd(ll a,ll b,ll &x,ll &y){
if(b==0) return x=1,y=0,a;
ll res=Exgcd(b,a%b,x,y);
ll z=x;
x=y;
y=z-(a/b)*y;
return res;
}
void Solve(){
read(A),read(B),read(C);
d=Exgcd(A,B,x,y);
if(C%d) return puts("-1"),void();
A/=d,B/=d,C/=d;
x*=C,y*=C;
x1=((x-1)%B+B)%B+1;
y2=GetY(x1);
y1=((y-1)%A+A)%A+1;
x2=GetX(y1);
cnt=(x2-x1)/B+1;
if(y2<=0) printf("%lld %lld\n",x1,y1);
else printf("%lld %lld %lld %lld %lld\n",cnt,x1,y1,x2,y2);
}
Ex.4 [NOIP2012 提高组] 同余方程
对式子进行变形:
利用 Exgcd 求解即可。
这是非常常用的变形技巧,也是当 \(a,b\) 互质但 \(b\) 不是质数时求逆元的方法。
Ex.5 青蛙的约会
设跳跃 \(k\) 次后两青蛙相遇,则可列出方程:
其中 \(S,L,C\) 为常数。
把 \(k,p\) 看作未知数,利用 Exgcd 求 \(k\) 的最小正整数解即可。
6. 中国剩余定理(CRT)
求下列同余方程组的解:
其中 \(m_1,m_2,m_3\dots,m_n\) 两两互质。
考虑如何构造出一个特解。
设 \(M=\prod m_i\),\(M_i=\dfrac{M}{m_i}\),\(t_i\) 为同余方程 \(t_iM_i\equiv 1\pmod{m_i}\) 的解。
那么方程的一个特解即为 \(x_0= \sum_\limits{i=1}^n a_iM_it_i\)。
道理也很简单,容易发现 \(M_i\) 是所有 \(\forall j \neq i\) 的 \(m_j\) 的倍数。对于 \(\forall i\),\(a_iM_it_i \equiv a_i \pmod{m_i}\),而对于 \(\forall j \neq i\),\(a_iM_it_i\equiv 0\pmod{m_j}\)。将 \(x_0\) 代入原方程可以使得原方程组成立。
那么方程的通解为 \(x_1=x_0+kM \ (x_1\geq 0,k\in\mathbb{Z})\),最小非负整数解为 \(x_0 \bmod M\)。
ll n,m[N],a[N],ans,M=1,x,y;
ll Exgcd(ll a,ll b,ll &x,ll &y){
if(!b) return x=1,y=0,a;
ll res=Exgcd(b,a%b,x,y);
ll z=x;
x=y,y=z-a/b*y;
return res;
}
void Solve(){
for(int i=1;i<=n;i++) M*=m[i];
for(int i=1;i<=n;i++){
ll Mi=M/m[i];
ll d=Exgcd(Mi,m[i],x,y);
x=((x-1)%(m[i]/d)+m[i]/d)%(m[i]/d)+1;
ans=(ans+SlowMul(SlowMul(x,Mi),a[i]))%M;
}
printf("%lld\n",ans);
}
7. 扩展中国剩余定理(ExCRT)
解下列方程组:
不要求 \(m_1,m_2\dots,m_n\) 两两互质。
此时中国剩余定理不再适用。考虑用扩欧合并方程组。
先考虑前两个方程。\(x\) 可以写成 \(k_1m_1+a_1\) 与 \(k_2m_2+a_2\) 的形式,\(m_1,m_2\in\mathbb{N}\)。
那么就可以得到一个方程:
利用扩欧求解出一组特解 \(k_1',k_2'\),并计算出此时 \(x\) 的特解 \(x_ 0\)。化简方程,两边同时除以 \(\gcd(m_1,m_2)\)。设新的方程为 \(Ak_1+Bk_2=C\)。
\(k_1\) 的通解:\(k_1=k_1'+pB\ (k_1\geq 0,p\in\mathbb{Z})\)。\(k_1\) 两个解之间相差 \(B\),那么 \(x\) 的两个解之间相差 \(Bm_1\),也就是 \(\dfrac{m_1m_2}{\gcd(m_1,m_2)}=\operatorname{lcm}(m_1,m_2)\)。\(x\) 的通解即为 \(x=x_0+t\operatorname{lcm}(m_1,m_2) \ (x\geq0,t\in\mathbb{Z})\)。
\(x\) 的通解可以继续写成同余方程的形式:
这样两个方程就合并成了一个方程。以此类推,共使用 \(n-1\) 次扩欧,最后就只剩下了一个同余方程。
假设剩下的方程为 \(x\equiv p \pmod{q}\),那么 \(x\) 的最小非负整数解即为 \(p \bmod q\)。
ll Solve(){
M=b[1],R=a[1];
for(int i=2;i<=n;i++){
ll A=M,B=b[i],C=a[i]-R;
C=(C%B+B)%B;
ll d=Exgcd(A,B,x,y);
if(C%d) return -1;
M=M/Exgcd(M,b[i],tmp1,tmp2)*b[i];
x=WangbaMul(x,C/d,M);
x=(x%(B/d)+(B/d))%(B/d);
R+=x*A; R%=M;
}
return R%M;
}