把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【学习笔记】中国剩余定理

声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。

前言

找了一些博客,好像都是直接给你结论然后再分析,顺序让我有点难接受,打算按自己的思路理一遍

这篇博客写的好棒!!

————————————————————————————٩(ˊᗜˋ)و✧*————————————————————————————

一、概念

给定 \(n\) 组非负整数 \(a_i\), \(b_i\),求解关于 \(x\) 的方程组的最小非负整数解。

\[\begin{cases}x\equiv b_1(\bmod a_1)\\x\equiv b_2(\bmod a_2)\\...\\x\equiv b_n(\bmod a_n)\end{cases} \]

保证 \(b_i\)\(b_j\) 互质

————————————————————————————٩(ˊᗜˋ)و✧*————————————————————————————

二、分析

方程有点多,我们先从一个方程解起

对于方程 \(x_i\equiv b_i(\bmod a_i)\) ,很显然 \(x_i = a_i + b_i * k \ ( \ k \in Z \ )\)

那么对于 \(n\) 个方程就有 \(n\)\(x\),我们想想能否将它们合并?

例如,对于 \(s = x_i + x_j\),我们想要 \(s\) 仍然满足 \(s\equiv b_i(\bmod a_i)\)\(s\equiv b_j(\bmod a_j)\)

显然,\(( \ x_i + k * b_i \ ) \ \% \ b_i = a_i\),所以只要 \(x_j\)\(b_i\) 的倍数即可,同样,\(x_i\) 也得为 \(b_j\) 的倍数

把它推广一下,即当 \(s = x_1 + x_2 + x_3 + ... + x_n\) 时,为满足 \(s \ \% \ b_i = a_i\),则 \(x_1,x_2...x_{i-1},x_{i+1}...x_n\) 得为 \(b_i\) 的倍数

整理一下可得,所有的 \(x_i\) 得为 \(b_j \ ( \ j \neq i \ )\) 的倍数,同时 \(x_i \ \% \ b_i = a_i\)

还有一个小技巧就是,找 \(x_i\) 的时候可以先找 \(\prod\limits_{j \neq i}a_j\)\(b_i\) 下的逆元(这里要用扩展欧几里得),再乘以 \(a_i\)

————————————————————————————٩(ˊᗜˋ)و✧*————————————————————————————

三、结论

转载自文章开头的博客

————————————————————————————٩(ˊᗜˋ)و✧*————————————————————————————

四、\(Code\)

代码为P1495 【模板】中国剩余定理(CRT)/曹冲养猪

#include<bits/stdc++.h>
#define F(i, x, y) for(int i = x; i <= y; ++ i)
#define ll long long
using namespace std;
ll read();
const int N = 15;
int n;
ll a[N], b[N];
ll mod = 1, ans, x, y;
int exgcd(ll a, ll b, ll &x, ll &y)
{
	if(b == 0)
	{
		x = 1, y = 0; 
		return a;
	}
	int r = exgcd(b, a % b, x, y), tmp = y;
	y = x - a / b * y, x = tmp;
	return r;
}
int main()
{
	n = read();
	F(i, 1, n) b[i] = read(), a[i] = read(), mod *= b[i];
	F(i, 1, n) 
	{
		exgcd(mod / b[i], b[i], x, y);
		ans = ((ans + a[i] * x * (mod / b[i])) % mod + mod) % mod;
	}
	printf("%lld\n", ans % mod);
} 
ll read()
{
	ll x = 0; 
	char c = getchar();
	while(c < '0' || c > '9') c = getchar();
	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
	return x;
}
posted @ 2020-04-16 21:51  Bn_ff  阅读(139)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end