数论基础+裴蜀定理+线性同余方程+乘法逆元+中国剩余定理
本文内容大多搬运来自oi wiki!
数论基础
整除
整除的定义:设
同余
同余的定义:设整数
否则,a 不同余于 b 模 m,b 不是 a 对模 m 的剩余。记作
这样的等式,称为模 m 的同余式,简称同余式。
根据整除的性质,上述同余式也等价于
如果没有特别说明,模数总是正整数。
式中的 b 是 a 对模 m 的剩余,这个概念与余数完全一致。通过限定 b 的范围,相应的有 a 对模 m 的最小非负剩余、绝对最小剩余、最小正剩余。
裴蜀定理
设 a,b 是不全为零的整数,则存在整数 x,y, 使得
进一步:
设自然数 a、b 和整数 n。a 与 b 互素(前提)。考察不定方程:ax+by=n,其中 x 和 y 为自然数。如果方程有解,称 n 可以被 a、b 表示。
记 C=ab-a-b。由 a 与 b 互素,C 必然为奇数。则有结论:对任意的整数 n,n 与 C-n 中有且仅有一个可以被表示。
即:可表示的数与不可表示的数在区间 [0,C] 对称(关于 C 的一半对称)。0 可被表示,C 不可被表示;负数不可被表示,大于 C 的数可被表示。
进一步的例题
相关资料
求不定方程
求
已知a,b,求解
利用扩展欧几里得算法求解,原理可见相关资料
int gcd(int a, int b){ if(b == 0) return a; else return gcd(b, a % b); } int gcd(int a,int b){ if(b==0) return a; else return gcd(b,a%b); } int exgcd(int a,int b,int &x,int &y){//返回gcd if(b == 0) {x=1, y=0; return a;} int x1, y1, d; d = exgcd(b, a%b, x1, y1); x = y1, y = x1-a/b*y1; return d; } void exgcd(int a,int b,int &x,int &y){//不返回gcd if(b==0){ x=1; y=0; return ; } exgcd(b,a%b,y,x); y-=a/b*x; return ; }
最终的
求
已知a,b,c,求解
- 若
,则先利用exgcd求得 的解,再乘以 ,即得原方程的特解 - 反之,即
,则无整数解
相关资料
525 不定方程 扩展欧几里得算法原理
扩展欧几里得算法(简单易懂,详细分析)
线性同余方程
形如
利用exgcd求解线性同余方程
代码:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; int exgcd(int a,int b,int &x,int &y){ if(b == 0){x = 1, y = 0; return a;} int x1, y1, d; d = exgcd(b, a%b, x1, y1); x = y1, y = x1-a/b*y1; return d; } int main(){ int a, b, m, x, y; scanf("%d%d%d", &a, &b, &m); int d = exgcd(a, m, x, y); if(b%d == 0) printf("%d", 1ll*x*b/d%m); else puts("none"); return 0; }
相关资料
乘法逆元
求解数n在模 p 意义下的乘法逆元
当a与m互质时,对于方程
解法一: 费马小定理(当m为质数时)
数a的乘法逆元
可利用快速幂方便求解
故,详见快速幂板子
解法二: 扩展欧几里得法(当
- 先将乘法逆元形式转化为不定方程形式,变形等价
- 再利用exgcd求解
的解x,那么 即为最终答案
exgcd板子:
void exgcd(int a, int b, int & x, int & y){ if(b == 0){ x = 1; y = 0; return; } exgcd(b, a % b, y, x); y -= a / b * x; return; } cout << (p + x % p) % p << '\n';
线性求解 中每个数关于 p 的逆元
迭代实现
inv[1] = 1; for(int i = 2; i <= n; ++ i){ inv[i] = (p - p / i) * inv[p % i] % p; cout << inv[i] << '\n'; }
相关资料
取余题目集合
- https://atcoder.jp/contests/abc275/tasks/abc275_b 小坑勿怪!!!
代码——qiansui_code - https://loj.ac/p/110 模板题
代码——qiansui_code——扩展欧几里得法
代码——qiansui_code——费马小定理
3.有意思的一题:
https://atcoder.jp/contests/abc298/tasks/abc298_d
运用到取余+快速幂+思维
中国剩余定理 CRT
中国剩余定理 (Chinese Remainder Theorem, CRT) 可求解如下形式的一元线性同余方程组(其中
上面的「物不知数」问题就是一元线性同余方程组的一个实例。
求解过程:
- 计算所有模数的积 n;
- 对于第 i 个方程:
计算
计算 在模 意义下的 逆元
计算 (不要对 取模) - 方程组在模 n 意义下的唯一解为:
板子:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; ll n, a[11], b[11]; ll exgcd(ll a,ll b,ll &x,ll &y){ if(b==0){x=1, y=0; return a;} ll d, x1, y1; d = exgcd(b, a%b, x1, y1); x = y1, y = x1-a/b*y1; return d; } ll CRT(ll m[], ll r[]){ ll M = 1, ans = 0; for(int i=1;i<=n;i++) M*=m[i]; for(int i=1; i<=n; i++){ ll c = M/m[i], x, y; exgcd(c, m[i], x, y); ans = (ans+r[i]*c*x%M)%M; } return (ans%M + M)%M; } int main(){ scanf("%lld", &n); for(int i = 1; i <= n; ++i) scanf("%lld%lld", a+i, b+i); printf("%lld\n", CRT(a,b)); return 0; }
相关资料
本文来自博客园,作者:Qiansui,转载请注明原文链接:https://www.cnblogs.com/Qiansui/p/16842829.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探