我是靠谱客的博主 优美咖啡,最近开发中收集的这篇文章主要介绍中国剩余定理(CRT)/曹冲养猪【模板】,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

>Link

luogu P1495


>Description

求解一元线性同余方程组 { x ≡ b 1 ( m o d a 1 ) . . . . . . x ≡ b n ( m o d a n ) left{begin{matrix}xequiv b_1(mod a_1) \ ...... \ xequiv b_n(mod a_n) end{matrix}right. xb1(moda1)......xbn(modan)
保证 a a a两两互质


>解题思路

#关于这道题
……因为用了unsigned long long调用太多内存爆了,所以只有60分,检查了好久(甚至还去对标 了)才检查出来要用longlong……

(笔记参考Bat特白)

#关于中国剩余定理

孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。
一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。 ——百度百科

求解一元线性同余方程组 { x ≡ 2 ( m o d 3 ) x ≡ 3 ( m o d 5 ) x ≡ 2 ( m o d 7 ) left{begin{matrix}xequiv 2(mod 3) \ xequiv 3(mod5) \ xequiv 2(mod7) end{matrix}right. x2(mod3)x3(mod5)x2(mod7)

将问题进行分解,使得(以下 m o d mod mod省略) { x 1 ≡ 2 ( 3 ) , x 1 ≡ 0 ( 5 ) , x 1 ≡ 0 ( 7 ) x 2 ≡ 0 ( 2 ) , x 2 ≡ 3 ( 5 ) , x 2 ≡ 0 ( 7 ) x 3 ≡ 0 ( 2 ) , x 3 ≡ 0 ( 5 ) , x 3 ≡ 2 ( 7 ) left{begin{matrix}x_1equiv 2(3),x_1equiv 0( 5),x_1equiv 0( 7) \ x_2equiv 0(2),x_2equiv 3(5),x_2equiv 0(7) \x_3equiv 0(2),x_3equiv 0(5), x_3equiv 2(7) end{matrix}right. x12(3),x10(5),x10(7)x20(2),x23(5),x20(7)x30(2),x30(5),x32(7)
此时 x = x 1 + x 2 + x 3 x=x_1+x_2+x_3 x=x1+x2+x3 x x x的性质依然满足

再将问题进行分解,看 x 1 x_1 x1如何求
y 1 ≡ 1 ( 3 ) , y 1 ≡ 0 ( 5 ) , y 1 ≡ 0 ( 7 ) y_1equiv 1(3),y_1equiv 0( 5),y_1equiv 0( 7) y11(3),y10(5),y10(7)
那么 x 1 = 2 ∗ y 1 x_1=2*y_1 x1=2y1

这样求出所有的 y y y x = 2 ∗ y 1 + 3 ∗ y 2 + 2 ∗ y 3 x=2*y_1+3*y_2+2*y_3 x=2y1+3y2+2y3
但是此时 x x x还不是最小解, x x x要不断减去 3 , 5 , 7 3,5,7 3,5,7的最小公倍数直到不能减(呃好吧其实就是直接取模

那么如何求 y y y??
因为 y 1 ≡ 1 ( 3 ) , y 1 ≡ 0 ( 5 ) , y 1 ≡ 0 ( 7 ) y_1equiv 1(3),y_1equiv 0( 5),y_1equiv 0( 7) y11(3),y10(5),y10(7),所以 y 1 y_1 y1一定是 5 5 5 7 7 7的公倍数,我们设 y 1 = 35 t y_1=35t y1=35t
那么现在就变成了 35 t ≡ 1 ( 3 ) 35tequiv 1(3) 35t1(3),可以转化成 35 t − 1 = 3 k 35t-1=3k 35t1=3k
再转化一下: 35 t − 3 k = 1 35t-3k=1 35t3k=1,这不就是exgcd吗!直接开始扩欧
(因为题目保证 a i a_i ai a j a_j aj互质,所以我们可以扩欧)


>代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
#define N 100000
using namespace std;

int n;
LL a[N], b[N], M, ans, m;

void ex_gcd (LL aa, LL bb, LL &x, LL &y)
{
	if (!bb) {x = 1, y = 0; return;}
	LL X = x, Y = y;
	ex_gcd (bb, aa % bb, X, Y);
	x = Y;
	y = X - (aa / bb) * Y;
}

int main()
{
	scanf ("%d", &n);
	M = 1;
	for (int i = 1; i <= n; i++)
	{
		scanf ("%lld%lld", &a[i], &b[i]);
		M *= a[i];
	}
	for (int i = 1; i <= n; i++)
	{
		m = M / a[i];
		LL x = 0, y = 0;
		ex_gcd (a[i], m, x, y);
		if (y <= 0) y += a[i];
		ans += m * y * b[i];
	}
	printf ("%lld", ans % M);
	return 0;
}

最后

以上就是优美咖啡为你收集整理的中国剩余定理(CRT)/曹冲养猪【模板】的全部内容,希望文章能够帮你解决中国剩余定理(CRT)/曹冲养猪【模板】所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部