【学习笔记】数学知识-同余
同余
- 取模运算性质
- 若整数 \(a\) 和整数 \(b\) 除以正整数 \(m\) 的余数相等,则称 \(a,b\) 模 \(m\) 同余,记为 \(a \equiv b \pmod{m}\) ;否则,称 \(a,b\) 模 \(m\) 不同余,记为 \(a \not\equiv b \pmod{m}\) 。
- 性质
- 自反性: \(a \equiv a \pmod{p}\)
- 对称性:若 \(a \equiv b \pmod{p}\) ,则 \(b \equiv a \pmod{p}\) 。
- 传递性:若 \(a \equiv b \pmod{p},b \equiv c \pmod{p}\) ,则 \(a \equiv c \pmod{p}\) ;若 \(a \equiv b \pmod{p},q|p\) ,则 \(a \equiv b \pmod{q}\) 。
- 同加性:若 \(a \equiv b \pmod{p}\) ,则 \(a+c \equiv b+c \pmod{p},a-c \equiv b-c \pmod{p}\) 。
- 同乘性:若 \(a \equiv b \pmod{p}\) ,则 \(a \times c \equiv b \times c \pmod{p}\) 。
- 若 \(ac \equiv bc \pmod{p}\) ,则 \(a \equiv b \pmod{\dfrac{p}{\gcd(c,p)}}\) 。
- 同幂性:若 \(a \equiv b \pmod{p}\) ,则 \(a^n \equiv b^n\pmod{p}\) 。
- 若 \(a \equiv b \pmod{p},a \equiv b \pmod{q}\) ,则 \(a \equiv b \pmod{\operatorname{lcm}(p,q)}\) 。
- 若 \(a \equiv b \pmod{p}\) ,则 \(p|(a-b)\) 。
- 性质
- 同余类
- 对于 \(\forall a \in[0,p-1]\) ,集合 \(\{a+kp\}(k \in \mathbb{Z})\) 的所有数模 \(p\) 同余,余数都为 \(a\) 。该集合称为一个模 \(p\) 的同余类,简记为 \(\overline{a}\) 。
- 剩余系
- 模 \(p\) 的同余类一共有 \(p\) 个,分别为 \(\overline{0},\overline{1},\overline{2}, \dots ,\overline{p-1}\) 。它们构成 \(p\) 的完全剩余系。
- \(1 \sim p\) 中与 \(p\) 互质的数代表的同余类共有 \(\varphi(p)\) 个,它们构成 \(p\) 的简化剩余系。
- \(p\) 的简化剩余系中的数满足与 \(p\) 互质且模 \(p\) 互不相同。
- 性质
- 若整数 \(a,b(1\le a,b\le p),p\) 满足 \(\gcd(a,p)= \gcd(b,p)=1\) ,有 \(a,b,(a \times b) \bmod p\) 属于 \(p\) 的简化剩余系。
- 若整数 \(a,b,x,p\) 满足 \(\gcd(a,p)=1\) ,则当 \(x\) 跑遍模 \(p\) 的简化剩余系时, \(ax\) 也跑遍模 \(p\) 的简化剩余系;当 \(x\) 跑遍模 \(p\) 的完全剩余系时, \(ax\) 也跑遍模 \(p\) 的完全剩余系;当 \(x\) 跑遍模 \(p\) 的完全剩余系时, \(ax+b\) 也跑遍模 \(p\) 的完全剩余系。
费马小定理
- 费马小定理:若 \(p\) 是质数,则对于任意整数 \(a\) ,有 \(a^p \equiv a \pmod{p}\) 。
- 证明
- 当 \(a \bmod p=0\) 时,显然结论成立。
- 当 \(a \bmod p \ne 0\) 时,不存在一组 \(x,y\) 满足 \(1 \le x,y<p,xa \equiv ya \pmod{p}\) 。因此 \(1 \sim p-1\) 所有数,乘以 \(a\) 之后对 \(p\) 取模,仍可得 \(1 \sim p-1\) 所有数。即 \(\prod\limits_{i=1}^{p-1} i \equiv \prod\limits_{i=1}^{p-1} ai \pmod{p}\) ,易知其中 \(\prod\limits_{i=1}^{p-1} i\) 与 \(p\) 互质,则 \(\prod\limits_{i=1}^{p-1}a \equiv 1 \pmod{p}\) ,即 \(a^{p-1} \equiv 1 \pmod{p}\) 。等式两边同乘 \(a\) ,得到 \(a^p \equiv a \pmod{p}\) 。
- 证明
- 变形
- 若 \(p\) 是质数,则对于任意整数 \(a\) ,有 \(a^{p-1} \equiv \begin{cases}0&a \bmod p=0\\1&a \bmod p \ne 0\end{cases} \pmod{p}\) 。
欧拉定理
- 欧拉定理:若正整数 \(a,p\) 满足 \(\gcd(a,p)=1\) ,则 \(a^{\varphi(p)} \equiv 1 \pmod{p}\) 。
- 证明
- 当 \(p\) 为质数时,有 \(a^{\varphi(p)}=a^{p-1}\) ,依据费马小定理,有 \(a^p \equiv a \pmod{p}\) ,故 \(a^{p-1} \equiv 1 \pmod{p}\) 。
- 当 \(p\) 不为质数时,设 \(S=\{ p_1,p_2, \dots ,p_{\varphi(p)}\}\)为 \(p\) 的简化剩余系,对于任意一对 \(i,j(1 \le i,j \le \varphi(p),i \ne j)\) ,有 \((a \times p_i) \bmod p \ne (a \times p_j) \bmod p\) ,且 \(a \times p_i,a \times p_j\) 均与 \(p\) 互质。因此 \(S\) 中所有数,乘以 \(a\) 之后对 \(p\) 取模,仍可得 \(S\) 中所有数,则 \(\prod\limits_{i=1}^{\varphi(p)} p_i \equiv \prod\limits_{i=1}^{\varphi(p)} ap_i \pmod{p}\) ,易知其中 \(\prod\limits_{i=1}^{\varphi(p)} p_i\) 与 \(p\) 互质,即 \(\prod\limits_{i=1}^{\varphi(p)}a \equiv 1 \pmod{p}\) ,即 \(a^{\varphi(p)} \equiv 1 \pmod{p}\) 。
- 应用
- 若正整数 \(a,p\) 满足 \(\gcd(a,p)=1\) ,则满足 \(a^x \equiv 1 \pmod{p}\) 的最小正整数 \(x_0\) 满足 \(x_0|\varphi(p)\) 。
- 证明
- 考虑反证法。假设满足 \(a^x \equiv 1 \pmod{p}\) 的最小正整数 \(x_0\) 不满足 \(x_0|\varphi(p)\) 。设 \(\varphi(p)=qx_0+r(0<r<x_0)\) 。因为 \(a^{x_0} \equiv 1 \pmod{p}\) ,所以 \(a^{qx_0} \equiv 1 \pmod{p}\) 。根据欧拉定理,有 \(a^{\varphi(p)} \equiv 1 \pmod{p}\) ,所以 \(a^r \equiv 1 \pmod{p}\) 。这与 \(x_0\) 最小矛盾。因此假设不成立,故 \(x_0|\varphi(p)\) 。
- 证明
- 若正整数 \(a,p,u,v\) 满足 \(\gcd(a,p)=1,a^{u} \equiv 1 \pmod{p},a^{v} \equiv 1 \pmod{p}\) ,则 \(a^{\gcd(u,v)} \equiv 1 \pmod{p}\) 。
- 证明
- 设 \(ux+vy= \gcd(u,v)\) ,取它的一组解满足 \(x>0,y \le 0\) ,则 \(a^{\gcd(u,v)} \equiv a^{\gcd(u,v)}(a^v)^{-y}=a^{\gcd(u,v)-vy}=a^{ux}=(a^u)^x \equiv 1^x \equiv 1 \pmod{p}\) 。
- 证明
- 若正整数 \(a,p\) 满足 \(\gcd(a,p)=1\) ,则满足 \(a^x \equiv 1 \pmod{p}\) 的最小正整数 \(x_0\) 满足 \(x_0|\varphi(p)\) 。
扩展欧拉定理
- 扩展欧拉定理:对于正整数 \(a,b,p\) 均有 \(a^b \equiv \begin{cases}a^{b \bmod \varphi(p)} &\gcd(a,p)=1 \\ a^{b} &\gcd(a,p) \ne 1,b<\varphi(p) \\ a^{b \bmod \varphi(p)+\varphi(p)} &\gcd(a,p) \ne 1,b \ge \varphi(p)\end{cases} \pmod{p}\) 。
- 证明
- 当 \(\gcd(a,p)=1\) 时,设 \(b=q \times \varphi(p)+r\) ,其中 \(0 \le r< \varphi(p)\) ,即 \(r=b \bmod \varphi(p)\) 。则有 \(a^b = a^{q \times \varphi(p)+r}=(a^{\varphi(p)})^q \times a^r \equiv 1^q \times a^r \equiv a^r= a^{b \bmod \varphi(p)} \pmod{p}\) 。
- 当 \(\gcd(a,p) \ne 1\) 时的证明极其复杂,请参考 link 或者 OI WiKi 中的证明。
- 例题
-
点击查看代码
ll read(ll p) { ll x=0,f=1,f2=0; char c=getchar(); while(c<'0'||'9'<c) { if(c=='-') { f=-1; } c=getchar(); } while('0'<=c&&c<='9') { x=x*10+c-'0'; if(x>=p)//当b>=phi(p) 时,公式才能应用 { f2=1; } x%=p; c=getchar(); } if(f2==1) { x+=p; } return x; } ll phi(ll n) { ll ans=n,i; for(i=2;i<=sqrt(n);i++) { if(n%i==0) { ans=ans/i*(i-1); while(n%i==0) { n/=i; } } } if(n>1) { ans=ans/n*(n-1); } return ans; } ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans%p; } int main() { ll a,b,phii; cin>>a>>p; phii=phi(p); b=read(phii); cout<<qpow(a,b,p)<<endl; return 0; }
-
乘法逆元
- 乘法逆元:若关于整数 \(a,b\) 的线性同余方程 \(ax \equiv 1 \pmod{b}\) 存在解,则将 \(x\) 称作 \(a\) 模 \(b\) 的乘法逆元(简称逆元),记作 \(a^{-1} \pmod{b}\) ,在不会引起误解时常常简记为 \(a^{-1}\) 。
- 貌似数奥中把这个叫做数论倒数。
- 若 \(b|a\) 时不存在 \(a\) 的逆元 \(a^{-1} \pmod{b}\) 。
- 特别地,有 \(1^{-1} \equiv 1 \pmod{b}\) 。
- 证明:对于 \(\forall b \in \mathbf{Z}\) ,有 \(1 \times 1 \equiv 1 \pmod{b}\) ,故 \(1\) 模 \(b\) 的逆元为 \(1\) 。
- 性质
- 若 \(n\) 为正整数,则 \(2^{-1} \equiv n+1 \pmod{2n+1}\) 。
- 证明:已知 \(2x \equiv 1 \pmod{2n+1}\) ,设 \(2x=(2n+1)k+1\) ,又因为 \(2x\) 为偶数, \(k\) 的最小正整数解为 \(1\) ,代入得 \(x=n+1\) 。
- 若 \(b\) 为质数,且 \(a<b\) ,则 \(a^{-1} \equiv a^{b-2} \pmod{b}\) 。
- 证明:依据费马小定理,有 \(a^{b-1} \equiv 1 \pmod{b}\) ,即 \(a \times a^{b-2} \equiv 1 \pmod{b}\) ,则 \(a\) 模 \(b\) 的乘法逆元为 \(a^{b-2}\) 。
- 若 \(\gcd(a,b)=1\) ,有 \((a^{-1})^{-1} \equiv a \pmod{b}\) 。
- 若 \(n\) 为正整数,则 \(2^{-1} \equiv n+1 \pmod{2n+1}\) 。
- 如何求逆元(边算边取模)
- 扩展欧几里得
-
限制条件: \(\gcd(a,b)=1\) 。
-
设 \(ax=bk+1,y=-k\) ,原方程可改写为 \(ax+by=1\) ,用 \(exgcd\) 解得一组特解 \(x_0,y_0\) ,\(x\) 的最小正整数解为 \((x+b)\bmod b\) 。
-
时间复杂度为 \(O(\log \max(a,b))\) 。
-
luogu P1082 [NOIP2012 提高组] 同余方程
点击查看代码
ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } else { ll d=exgcd(b,a%b,y,x); y-=a/b*x; return d; } } int main() { ll a,b,x=0,y=0; cin>>a>>b; exgcd(a,b,x,y); x=(x%b+b)%b; cout<<x<<endl; }
-
点击查看代码
const ll p=19260817; ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } else { ll d=exgcd(b,a%b,y,x); y-=a/b*x; return d; } } int main() { ll a,c,d,x=0,y=0; c=read(); a=read(); d=exgcd(a,p,x,y); if(c%d==0) { x=(x*c/d)%p; x=(x%p+p)%p; cout<<x<<endl; } else { cout<<"Angry!"<<endl; } return 0; }
-
- 快速幂+费马小定理
-
限制条件: \(b\) 为质数。
-
因为 \(b\) 为质数, \(ax \equiv 1 \pmod{b}\) ,依据费马小定理,则 \(ax \equiv 1 \equiv a^{b-1} \pmod{b}\) ,故 \(x \equiv a^{b-2} \pmod{b}\) 。用快速幂求出 \(a^{b-2} \bmod b\) ,即为所求。
-
时间复杂度为 \(O(\log b)\) 。
-
luogu P1082 [NOIP2012 提高组] 同余方程
点击查看代码
ll qpow(ll a,ll b,ll p) { ll ans=1; a%=p; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans%p; } int main() { ll a,b; cin>>a>>b; cout<<qpow(a,b-2,b)<<endl; }
-
- 快速幂+欧拉定理
-
限制条件: \(\gcd(a,b)=1\) 。
-
因为 \(\gcd(a,b)=1,ax \equiv 1 \pmod{b}\) ,依据欧拉定理,则 \(ax \equiv 1 \equiv a^{\varphi(b)} \pmod{b}\) ,故 \(x \equiv a^{\varphi(b)-1} \pmod{b}\) 。用快速幂求出 \(a^{\varphi(b)-1} \bmod b\) ,即为所求。
-
如果不预处理欧拉函数,时间复杂度为 \(O(\sqrt{b} \times \log \varphi(b))\) 。
-
luogu P1082 [NOIP2012 提高组] 同余方程
点击查看代码
ll phi(ll n) { ll ans=n,i; for(i=2;i<=sqrt(n);i++) { if(n%i==0) { ans=ans/i*(i-1); while(n%i==0) { n/=i; } } } if(n>1) { ans=ans/n*(n-1); } return ans; } ll qpow(ll a,ll b,ll p) { ll ans=1; a%=p; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans%p; } int main() { ll a,b; cin>>a>>b; cout<<qpow(a,phi(b)-1,b)<<endl; }
-
- 线性求 \(1 \sim n\) 或单个数的逆元(递推/递归)
-
限制条件: \(b\) 为质数。
-
设 \(k=\left\lfloor\dfrac{b}{i}\right\rfloor,r=b \bmod i\) ,此时有 \(b=k \times i+r\equiv 0 \pmod{b}\) 。两边同时乘以 \(i^{-1} \times r^{-1}\) 得 \(k \times r^{-1}+i^{-1}\equiv 0 \pmod{b}\) ,移项得 \(i^{-1}\equiv -k \times r^{-1} \pmod{b}\) ,将 \(k=\left\lfloor\dfrac{b}{i}\right\rfloor,r=b \bmod i\) 代入得 \(i^{-1}\equiv -\left\lfloor\dfrac{b}{i}\right\rfloor \times (b \bmod i)^{-1} \pmod{b}\) ,考虑消除负数取模对答案的影响,故推出逆元:\(\\i^{-1} \equiv \begin{cases}1,&i=1\\(b-\left\lfloor\dfrac{b}{i}\right\rfloor) \times (b \bmod i)^{-1}&i \ne 1\end{cases} \pmod{b}\)
-
递推求 \(n\) 个数的逆元, \(O(n)\) 预处理, \(O(1)\) 查询。
-
递归+记忆化求 \(n\) 个数的逆元, \(O(n)\) 预处理, \(O(1)\) 查询。
- 递归求任意一个正整数 \(n\) 的逆元,时间复杂度为 \(O(n^{\frac{1}{3}})\) 。
-
点击查看代码
ll inv[3000001]; int main() { ll n,p,i; cin>>n>>p; inv[1]=1; cout<<"1"<<endl; for(i=2;i<=n;i++) { inv[i]=(p-p/i)*inv[p%i]%p; cout<<inv[i]<<endl; } return 0; }
-
- 线性求任意 \(n\) 个数的逆元(离线)
- 限制条件: \(b\) 为质数。
- 对于 \(1 \le i \le n\) ,令 \(mul[i]=\prod\limits_{k=1}^{i} a_k\) 。利用 \(exgcd\) 或快速幂计算 \(invc[n]=mul[n]^{-1}\) 。对于 \(1 \le i \le n-1\) ,此时有 \(invc[i]=invc[i+1] \times a_{i+1}=mul[i]^{-1}\) 。对于 \(1 \le i \le n\) ,有 \(a_i^{-1}=mul[i-1] \times invc[i]\) 。
- 时间复杂度为 \(O(n+\log b)\) 。
- 例题
-
点击查看代码
ll mul[3000001],invc[3000001],inv[3000001],w[3000001];//防止重名,此处的w[]即为上文的a[] ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans%p; } int main() { ll n,p,i; cin>>n>>p; mul[0]=1; for(i=1;i<=n;i++) { w[i]=i; mul[i]=((mul[i-1]%p)*(w[i]%p))%p; } invc[n]=qpow(mul[n],p-2,p); for(i=n-1;i>=1;i--) { invc[i]=((invc[i+1]%p)*((w[i+1])%p))%p; } for(i=1;i<=n;i++) { inv[i]=((invc[i]%p)*(mul[i-1]%p))%p; cout<<inv[i]<<endl; } return 0; }
-
- 扩展欧几里得
- 例题
威尔逊定理
- 威尔逊定理:若 \(p\) 为质数,则有 \((p-1)! \equiv -1 \pmod{p}\) 。
- 证明
- 当 \(p=2\) 时,因为规定 \(0! =1\) ,所以原结论成立。
- 当 \(p \ne 2\) 时,根据逆元定义,对于 \(i,j \in[2,p-2]\) ,且 \(i \ne j\) ,均有 \(i^{-1} \pmod{p},j^{-1} \pmod{p} \in[2,p-2],i^{-1} \pmod{p} \ne j^{-1} \pmod{p}\) ,所以逆元是一一对应的,故 \((p-1)! \equiv 1^{\frac{p-3}{2}} \times 1 \times (p-1) \equiv-1 \pmod{p}\) 。
- 例题
- luogu T340175 Fermat-1
- \(n!+1\) 的次小约数等价于 \(n!+1\) 的最小质因子。故若 \(d\) 不为质数,则无解;若 \(d\) 为质数,依据威尔逊定理,易知 \(d-1\) 即为满足题意的一组解。
- luogu T340175 Fermat-1
中国剩余定理(孙子定理)
-
中国剩余定理(孙子定理):给定 \(n\) 个两两互质的整数 \(m_1,m_2, \dots,m_n\) ,设 \(mul=\prod\limits_{i=1}^{n}m_i,r_i=\dfrac{mul}{m_i}\) ,则对于任意的 \(n\) 个整数 \(a_1,a_2, \dots,a_n\) ,方程组 \(\begin{cases}x \equiv a_1 \pmod{m_1} \\ x \equiv a_2 \pmod{m_2} \\ \dots \\ x \equiv a_n \pmod{m_n} \end{cases}\) 在模 \(mul\) 意义下的唯一解为 \(x=\sum\limits_{i=1}^{n}a_ic_i(c_i^{-1} \pmod{mul})\) ,通解可以表示为 \(x+k \times mul(k \in \mathbb{Z})\) 。
-
证明
- 原方程组在模 \(mul\) 意义下的存在解。
- 因为 \(r_i=\dfrac{mul}{m[i]}\) 是除 \(m_i\) 所有模数的倍数,所以对于任意整数 \(j(1 \le j \le n)\) 均有 \(a_jc_j(c_j^{-1} \pmod{mul}) \equiv \begin{cases} a_i & i=j \\ 0 & i \ne j\end{cases} \pmod{m_i}\) ,所以代入 \(x=\sum\limits_{i=1}^{n}a_ir_i(r_i^{-1} \pmod{mul})\) ,原方程组成立。
- 原方程组在模 \(mul\) 意义下的存在唯一解。
- 假设原方程组在模 \(mul\) 意义下的存在第二个解 \(x'\) ,则一定存在一个 \(i\) 满足 \(x \not\equiv x' \pmod{m_i}\) ,故假设不成立,原结论成立。
- 原方程组在模 \(mul\) 意义下的存在解。
-
代码实现
点击查看代码
ll crt(ll n) { ll mul=1,ans=0,x,y,r,i; for(i=1;i<=n;i++) { mul*=m[i]; } for(i=1;i<=n;i++) { r=mul/m[i]; x=y=0; exgcd(r,m[i],x,y);//m_i两两互质并不代表m_i为质数 ans=(ans+(a[i]*r%mul)*(x+m[i])%mul)%mul;//因为exgcd求出的x可能为负数,故需要+m[i] } return ans; }
-
例题
- luogu P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪
- UVA756 Biorhythms
- 注意解的下限是有限制的。
- luogu P3868 [TJOI2009] 猜数字
- 因为 \(a_i\) 可能为负数,所以需要有
a[i]=(a[i]+m[i])%m[i];
。
- 因为 \(a_i\) 可能为负数,所以需要有
扩展中国剩余定理
-
扩展中国剩余定理所解决的问题和中国剩余定理所解决的问题相同,但不保证 \(m_i\) 两两互质。
-
算法流程
- 对于第 \(1\) 个方程,有 \(x=a_1\) 是第 \(1\) 个方程的一个解。
- 设已经求出了前 \(i-1\) 个方程所构成的方程组的一个解 \(x\) ,且有 \(mul= \operatorname{lcm}(m_1,m_2, \dots,m_{i-1}),l=x \bmod mul\) ,则 \(x+k \times mul(k \in \mathbb{Z})\) 是前 \(i-1\) 个方程所构成的方程组的通解,即 \(x \equiv l \pmod{mul}\) 。
- 对于第 \(i\) 个方程,其与前 \(i-1\) 个方程组成了一个方程组 \(\begin{cases}x \equiv l \pmod{mul} \\ x \equiv a_i \pmod{m_i} \end{cases}\) ,即 \(k \times mul+y \times m_i=a_i-l\) ,此方程有解当且仅当 \(\gcd(mul,m_i)|(a_i-l)\) 。若有解,则 \(x'=x+k \times mul\) 是前 \(i\) 个方程所构成的方程组的一个解。
-
代码实现
点击查看代码
ll excrt(ll n) { ll mul=m[1],ans=a[1],x,y,c,d,i; for(i=2;i<=n;i++) { x=y=0; c=(a[i]-ans%m[i]+m[i])%m[i];//减法取模注意先加模数再取模 d=exgcd(mul,m[i],x,y); if(c%d==0) { ans+=(((x+m[i])%m[i])*(c/d)%m[i])*mul;//exgcd解出来的x可能是负数 mul=lcm(mul,m[i]); ans=(ans%mul+mul)%mul; } else { return -1; } } return (ans+mul)%mul; }
-
例题
- luogu P4777 【模板】扩展中国剩余定理(EXCRT)
- LibreOJ 10213. 「一本通 6.4 例 5」Strange Way to Express Integers
- CF787A The Monster
- 注意解的下限是有限制的。
- luogu P4774 [NOI2018] 屠龙勇士
-
设 \(s_i\) 表示攻击第 \(i\) 头巨龙时所用剑的攻击力,则转换为求方程组 \(\begin{cases}s_1x \equiv a_1 \pmod{m_1} \\ s_2x \equiv a_2 \pmod{m_2} \\ \dots \\ s_nx \equiv a_n \pmod{m_n} \end{cases}\) 不小于 \(\max\limits_{i=1}^{n} \{ \left\lceil\dfrac{a_i}{s_i}\right\rceil \}\) 的最小非负整数解。接下来和扩展剩余定理推导内容除 \(mul\) 的取值外基本一致。
-
设已经求出了前 \(i-1\) 个方程所构成的方程组的一个解 \(x\) ,且有 \(mul= \operatorname{lcm}(\dfrac{m_1}{\gcd(m_1,s_1)},\dfrac{m_2}{\gcd(m_2,s_2)}, \dots,\dfrac{m_{i-1}}{\gcd(m_{i-1},s_{i-1})}),l=x \bmod mul\) ,则 \(x+k \times mul(k \in \mathbb{Z})\) 是前 \(i-1\) 个方程所构成的方程组的通解,即 \(x \equiv l \pmod{mul}\) 。
- 第 \(i\) 个方程实际上是 \(x \equiv x'' \pmod{\dfrac{m_i}{\gcd(m_i,s_i)}}\) ,其中 \(x''\) 是 \(s_ix''+m_iy=a_i\) 的一组特解。故在合并同余方程时,模数已经发生由原来的 \(m_i\) 变成了 \(\dfrac{m_i}{\gcd(m_i,s_i)}\) 。
-
对于第 \(i\) 个方程,其与前 \(i-1\) 个方程组成了一个方程组 \(\begin{cases}x \equiv l \pmod{mul} \\ s_ix \equiv a_i \pmod{m_i} \end{cases}\) ,即 \(k \times mul \times s_i+y \times m_i=a_i-l \times s_i\) ,此方程有解当且仅当 \(\gcd(mul \times s_i,m_i)|(a_i-l \times s_i)\) 。若有解,则 \(x'=x+k \times mul\) 是前 \(i\) 个方程所构成的方程组的一个解。
点击查看代码
ll excrt(ll n) { ll mul=1,ans=0,x,y,c,d,i,maxx=0; for(i=1;i<=n;i++) { x=y=0; it=s.upper_bound(a[i]);//注意是不大于 if(it!=s.begin()) { it--; } maxx=max(maxx,(ll)ceil(1.0*a[i]/(*it))); c=(a[i]-((*it)%m[i])*(ans%m[i])%m[i]+m[i])%m[i]; d=exgcd((*it)*mul,m[i],x,y); if(c%d==0) { ans+=(((x+m[i])%m[i])*(c/d)%m[i])*mul; mul=lcm(mul,m[i]/gcd(m[i],(*it))); ans=(ans%mul+mul)%mul; } else { return -1; } s.erase(it); s.insert(atk[i]); } return ans+(ll)ceil(1.0*(maxx-ans)/mul)*mul; }
-
高次同余方程
- 形如 \(a^{x} \equiv b \pmod{p}\) ,其中已知 \(a,b,p\) ,求非负整数解 \(x\) 。
- 当 \(\gcd(a,p)=1\) ,但不保证 \(p \in \mathbb{P}\) 时,使用
Baby Step,Giant Step
/大步小步算法求解。-
由欧拉定理,有 \(a^{\varphi(p)} \equiv 1 \pmod{p}\) ,即循环节为 \(\varphi(p)-1\) ,故只找到最小的一个 \(x \in [0,\varphi(p)-1]\) 即可得到所有满足条件的 \(x\) 。
-
算法流程
- 设 \(x=i \times \left\lceil \sqrt{p} \right\rceil-j\) ,其中 \(j \in [0,\left\lceil \sqrt{p} \right\rceil)\) ,则方程改写为 \(a^{i \times \left\lceil \sqrt{p} \right\rceil-j} \equiv b \pmod{p}\) 。
- 又因为 \(a,p\) 互质,移项得到 \((a^{\left\lceil \sqrt{p} \right\rceil})^{i} \equiv a^{j}b \pmod{p}\)
- 同时也解释了为什么要求 \(a,p\) 互质。
- 对于每个 \(j \in [0,\left\lceil \sqrt{p} \right\rceil)\) ,将 \(a^{j}b \bmod{p}\) 插入到一个哈希表中,接着枚举 \(i \in [0,\left\lceil \sqrt{p} \right\rceil]\) ,计算出 \((a^{\left\lceil \sqrt{p} \right\rceil})^{i} \bmod{p}\) 后在哈希表中查找即可。
-
代码实现
点击查看代码
ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } ll bsgs(ll a,ll b,ll p) { if(1%p==b%p) { return 0; } else { map<ll,ll>vis; ll k=sqrt(p)+1,i,sum; for(i=0;i<=k-1;i++) { vis[b*qpow(a,i,p)%p]=i; } a=qpow(a,k,p); for(i=0;i<=k;i++) { sum=qpow(a,i,p); if(vis.find(sum)!=vis.end()) { if(i*k-vis[sum]>=0) { return i*k-vis[sum]; } } } return -1; } }
-
例题
-
- 当不保证 \(\gcd(a,p)=1\) ,但 \(p \in \mathbb{P}\) 时,可以转化为
Baby Step,Giant Step
求解。- 由于不保证 \(\gcd(a,p)=1\) ,故当 \(a \equiv b \equiv 0 \pmod{p}\) 或 \(\gcd(a,p)=1\) 时,同余方程存在非负整数解,其中前者的最小非负整数解为 \(x=1\) ,后者则可以通过
Baby Step,Giant Step
求解;否则不存在解。 - 例题
- 由于不保证 \(\gcd(a,p)=1\) ,故当 \(a \equiv b \equiv 0 \pmod{p}\) 或 \(\gcd(a,p)=1\) 时,同余方程存在非负整数解,其中前者的最小非负整数解为 \(x=1\) ,后者则可以通过
- 当不保证 \(\gcd(a,p)=1\) 和不保证 \(p \in \mathbb{P}\) 时,使用扩展
Baby Step,Giant Step
算法求解。-
设 \(d_{1}=\gcd(a,p)\) ,若 \(d_{1} \nmid b\) 则无解,否则同余两边同时除以 \(d_{1}\) ,得到 \(\frac{a}{d_{1}}a^{x-1} \equiv \frac{b}{d_{1}} \pmod{\frac{p}{d_{1}}}\) 。
-
若 \(a,\frac{p}{d_{1}}\) 仍不互质则继续取 \(d_{2}=\gcd(a,\frac{p}{d_{1}})\) ,同余两边同时除以 \(d_{2}\) 得到 \(\frac{a^{2}}{d_{1}d_{2}}a^{x} \equiv \frac{b}{d_{1}d_{2}} \pmod{\frac{p}{d_{1}d_{2}}}\) 。
-
重复这个过程直至 \(\gcd(a,\frac{p}{\prod\limits_{i=1}^{k}d_{i}})=1\) ,此时有 \(\frac{a^{k}}{\prod\limits_{i=1}^{k}d_{i}}a^{x-k} \equiv \frac{b}{\prod\limits_{i=1}^{k}d_{i}} \pmod{\frac{p}{\prod\limits_{i=1}^{k}d_{i}}}\) 。
-
因为 \(\gcd(a,\frac{p}{\prod\limits_{i=1}^{k}d_{i}})=1\) ,所以 \(\gcd(\frac{a^{k}}{\prod\limits_{i=1}^{k}d_{i}},\frac{p}{\prod\limits_{i=1}^{k}d_{i}})=1\) ,乘过去后求逆元就和正常的
Baby Step,Giant Step
算法一样了。 -
对于 \(x<k\) 的情况,在求 \(k\) 的过程中判断即可。
-
代码实现
点击查看代码
ll qpow(ll a,ll b,ll p) { ll ans=1; while(b) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0; return a; } else { ll d=exgcd(b,a%b,y,x); y-=a/b*x; return d; } } ll inv(ll a,ll p) { ll x,y; exgcd(a,p,x,y); return (x%p+p)%p; } ll bsgs(ll a,ll b,ll p) { if(1%p==b%p) { return 0; } else { unordered_map<ll,ll>vis; ll k=sqrt(p)+1,i,sum=1; for(i=0;i<=k-1;i++) { b=(i==0)?b:b*a%p; vis[b]=i; } a=qpow(a,k,p); for(i=0;i<=k;i++) { sum=(i==0)?sum:sum*a%p; if(vis.find(sum)!=vis.end()) { if(i*k-vis[sum]>=0) { return i*k-vis[sum]; } } } return -1; } } ll exbsgs(ll a,ll b,ll p) { b%=p;//防止后面判 b%d==0 时出错 if(b==1||p==1)//特判 0 的情况 { return 0; } else { ll x,y,d=exgcd(a,p,x,y),k=0,mul=1; while(d!=1) { if(b%d==0) { k++; b/=d; p/=d; mul=(a/d)*mul%p; if(mul==b)//已经是答案 { return k; } else { d=exgcd(a,p,x,y); } } else { return -1; } } ll ans=bsgs(a,b*inv(mul,p)%p,p); return (ans!=-1)*k+ans; } }
-
例题
-
- 当 \(\gcd(a,p)=1\) ,但不保证 \(p \in \mathbb{P}\) 时,使用
- 形如 \(x^{a} \equiv b \pmod{p}\) ,其中已知 \(a,b,p\) ,求非负整数解 \(x\) 。
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/17641004.html,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。