中国剩余定理及其扩展定理 学习笔记
中国剩余定理及其扩展定理 学习笔记
中国剩余定理,又叫孙子定理,最早出现在我国古代著作《孙子算经》中,OI 中常称其为 CRT(China Remainder Theorem)。
问题
CRT 用于求解线性同余方程组问题,且模数互质:
求
CRT
令
则
显然地,最小的非负整数解就是
这其实是一个构造性的算法,接下来证明
证明:
, , 是其一个解。 对于
,所以 。 又
,所以 .
注意到
ExCRT
用于解决线性同余方程组模数不互质的情况,ExCRT 其实和 CRT 没什么关系。
考虑一个同余方程组:
如果能把它们两个合并成一个方程,然后迭代地合并所有方程,最后得到一个唯一的同余方程,岂不美哉?
先考虑把方程拿出同余系:
发现这是一个 ExGcd(aka 裴蜀定理)的形式,方程无解当且仅当
所以把通解代入一开始其中一个方程中得到:
至此,我们将两个同余方程合并为一个同余方程,重复
C++ 实现
Problem: P4777 【模板】扩展中国剩余定理(EXCRT)
// Problem: P4777 【模板】扩展中国剩余定理(EXCRT)
// Contest: Luogu
// Author: Moyou
// Copyright (c) 2023 Moyou All rights reserved.
// Date: 2023-11-11 13:26:13
#include <algorithm>
#include <iostream>
#define int long long
#define ll __int128
using namespace std;
const int N = 1e5 + 10;
int n, p[N], a[N];
int exgcd(ll a, ll &x, ll b, ll &y) {
if(!b) return x = 1, y = 0, a;
ll d = exgcd(b, y, a % b, x);
return y -= a / b * x, d;
}
int excrt() {
for(ll i = n - 1, k1, k2, d; i; i --) {
d = __gcd(p[i], p[i + 1]);
if((a[i + 1] - a[i]) % d) return -1; // 本题中不存在无解,但是无解情况不要漏
exgcd(p[i], k1, p[i + 1], k2);
k1 = k1 * (a[i + 1] - a[i]) / d % (p[i + 1] / d);
a[i] += k1 * p[i], p[i] = p[i] / __gcd(p[i], p[i + 1]) * p[i + 1], a[i] %= p[i];
}
return (a[1] % p[1] + p[1]) % p[1];
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1; i <= n; i ++) cin >> p[i] >> a[i];
cout << excrt() << '\n';
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战