中国剩余定理
问题
对于以上同余方程组,求解改同余方程组的未知数
中国剩余定理(CRT)
设
- 所有模数的积
- 计算第
个方程的 - 计算
模 意义下的逆元 - 结果
由于一般题目中的
这是需要扩展中国剩余定理求解 。
扩展中国剩余定理(EXCRT)
问题改为求
对于前两个方程
可以转化为丢番图方程
所以,
由裴蜀定理
当
当
由扩欧算法
通解为
所以
数论中我们记
前两个方程等价合并为一个方程
其中
所以
[AcWing204] 表达整数的奇怪方式
题目描述
给定
输入格式
第
第
输出格式
输出最小非负整数
数据范围
所有
输入样例:
2 8 7 11 9
输出样例:
31
算法
扩展中国剩余定理模版题。
C++ 代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 30; ll a[N],m[N]; int n; 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 excrt(ll a[], ll m[]) { ll m1, m2, a1, a2, p, q; m1 = m[1], a1 = a[1]; for (int i = 2; i <= n; i++){ m2 = m[i], a2 = a[i]; ll d = exgcd(m1, m2, p, q);// d=(m1,m2),同时计算m1p+m2q=1的特解(q=-y) if ((a2 - a1) % d) return -1; p = p * (a2 - a1) / d;// 这是m1p+m2q=a2-a1特解 // 保证m2/d为正数 p = (p % abs(m2 / d) + abs(m2 / d)) % abs(m2 / d);// 由于p可能是整数,需要加余取余操作变为最小正整数 a1 = m1 * p + a1; m1 = m1 * m2 / d; } return (a1 % m1 + m1) % m1;// 同上 } int main() { cin >> n; // 这里与题目相反,一般是m是余数 for (int i = 1; i <= n; i++) cin >> m[i] >> a[i]; cout << excrt(a, m) << endl; return 0; }
P4777 【模板】扩展中国剩余定理(EXCRT)
题目描述
给定
输入格式
输入第一行包含整数
接下来
输出格式
输出一行,为满足条件的最小非负整数
输入输出样例 #1
输入 #1
3 11 6 25 9 33 17
输出 #1
809
说明/提示
对于
请注意程序运行过程中进行乘法运算时结果可能有溢出的风险。
数据保证有解。
算法
同样为扩展中国剩余定理的板子题。
但是注意不要越界,函数
代码
#include <bits/stdc++.h> using namespace std; #define IOS ios::sync_with_stdio(false) typedef long long ll; const int N = 1e5 + 10; ll a[N], b[N]; int n; ll mul(ll a, ll b, ll m)// 计算a * b % m { auto res = 0ll; while (b){ if (b & 1) res = (res + a) % m; a = (a + a) % m; b >>= 1; } return res; } ll exgcd(ll a, ll b, ll &x, ll &y) { if (b == 0){ x = 1, y = 0; return a; } ll d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } inline ll get(ll a, ll b)// 保证最小整数 { return (a % b + b) % b; } ll excrt(ll a[], ll m[]) { ll m1, m2, a1, a2, p, q; m1 = m[1], a1 = a[1]; auto ans = 0ll; for (int i = 2; i <= n; i++){ m2 = m[i], a2 = a[i]; ll d = exgcd(m1, m2, p, q); // 合并成ap + bq = c ll a = m1, b = m2, c = get(a2 - a1, m2); if (c % d) return -1; p = mul(p, c / d, b / d); ans = a1 + m1 * p; m1 = m2 / d * m1; ans = get(ans, m1); a1 = ans; } return ans; } int main() { IOS; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i] >> b[i]; cout << excrt(b, a) << endl; return 0; }
分类:
数论
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~