【洛谷 P1495 】曹冲养猪【中国剩余定理(CRT)】【模板】

102 篇文章 0 订阅
28 篇文章 0 订阅

在这里插入图片描述


解题思路

可以先参考看看》》中国剩余定理(CRT )(跳过前面的铺垫直接看解法)

其实思路就是上面那个文章中的思路。首先,依题意得:
x ≡ b i ( m o d a i ) x≡b_i(mod a_i) xbi(modai)
而这样的方程有很多,自然变成一个同余方差组。

我们先举个解方程的例子,再带回题目中看:在这里插入图片描述
再将问题进行分解,看 x 1 x_1 x1 如何求:
我们可以先求出 同余方程 x x 1 ≡ 1 ( 3 ) , x x 1 ≡ 0 ( 5 ) , x x 1 ≡ 0 ( 7 ) xx_1\equiv 1(3),xx_1\equiv 0( 5),xx_1\equiv 0( 7) xx11(3),xx10(5),xx10(7) 的解 x x 1 xx_1 xx1
那么 x 1 = 2 ∗ x x 1 x_1=2*xx_1 x1=2xx1

x x 1 xx_1 xx1
x x 1 ≡ 1 ( 3 ) , x x 1 ≡ 0 ( 5 ) , x x 1 ≡ 0 ( 7 ) xx_1\equiv 1(3),xx_1\equiv 0( 5),xx_1\equiv 0( 7) xx11(3),xx10(5),xx10(7) 所以xx一定是 5和 7的公倍数,我们设 y 1 = 35 t y_1=35t y1=35t 那么现在就变成了 35 t ≡ 1 ( 3 ) 35t\equiv 1(3) 35t1(3),可以转化成 35 t − 1 = 3 k 35t-1=3k 35t1=3k 再转化一下: 35 t − 3 k = 1 35t-3k=1 35t3k=1

这样就变成一个 e x g c d exgcd exgcd,扩欧求出t。

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

回到题目,把 x ≡ b i ( m o d a i ) x≡b_i(mod a_i) xbi(modai)转化为: b i + a i y = x b_i+a_iy=x bi+aiy=x ——> x − a i y = b i x-a_iy=b_i xaiy=bi
WOW,和上面的方程如此相似,扩欧走起。。
(因为题目保证 a i a_i ai a j a_j aj 互质,所以我们可以扩欧)


代码

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long

using namespace std;

int n;
ll a[100010],b[100010],maxn,ans;

void exgcd(ll a,ll b,ll &x,ll &y)
{
	if(b==0)
	{
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,x,y);
	ll z=x;
	x=y;
	y=z-(a/b)*y;
}

int main() {
	scanf("%d",&n);
	maxn=1;
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&a[i],&b[i]);
		maxn=maxn*a[i];
	}
	for(int i=1;i<=n;i++)
	{
		ll k=maxn/a[i];
		ll x=0,y=0;
		exgcd(k,a[i],x,y);
		if(x<=0)x+=a[i];
		ans=ans+x*k*b[i];
	}
	printf("%lld",ans%maxn);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值