曹冲养猪(中国剩余定理模板题+exgcd求逆元)

曹冲养猪(中国剩余定理模板题+exgcd求逆元)

source:洛谷P1495
时间限制:1.00s
内存限制:125.00MB

题目描述

自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪,可是曹冲满不高兴,于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。举个例子,假如有16头母猪,如果建了3个猪圈,剩下1头猪就没有地方安家了。如果建造了5个猪圈,但是仍然有1头猪没有地方去,然后如果建造了7个猪圈,还有2头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总,你该怎么办?

输入格式

第一行包含一个整数n (n <= 10) – 建立猪圈的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个猪圈,有bi头猪没有去处。你可以假定ai,aj互质.

输出格式

输出包含一个正整数,即为曹冲至少养母猪的数目。

输入1

3
3 1
5 1
7 2

输出1

16

题解

先了解一下中国剩余定理(巨佬请直接跳过
图片来自百度百科
好了接下来你已经明白答案显然就是
在这里插入图片描述
其中
在这里插入图片描述
t i t_i 可以用 e x g c d exgcd 求出,看到这里这题突然就变得索然无味了

这道题还有几个坑,首先用快速幂求逆元会WA,怀疑是爆LL了,其次对ans取模时要放在下面,若是直接在括号里加上mod(代码46行)也会WA,怀疑也是爆LL了……

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#define m_p make_pair
#define p_i pair<int, int> 
#define maxn 12
#define maxm 505
#define _for(i, a) for(LL i = 0; i < (a); i++)
#define _rep(i, a, b) for(LL i = (a); i <= (b); i++)
#define outval(a) cout<<#a<<": "<<a<<"\n"
using namespace std;
typedef long long LL;
const LL MAXN = 110;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
typedef vector< double > vec;
typedef vector< vec > mat;

const double eps = 1e-8;

vector<LL> B, M;
LL mod;

void init() {
	mod = 1;
}

void exgcd(LL a, LL b, LL&x, LL&y) {//用快速幂求逆元会WA,怀疑数据溢出了
	if (!b) { x = 1; y = 0; }
	else {
		exgcd(b, a % b, y, x);
		y -= a / b * x;
	}
}

void Crt(vector<LL>&B, vector<LL>M) {
	LL ans = 0, x, y;
	_for(i, B.size()) {
		LL m = mod / M[i];
		exgcd(m, M[i], x, y);
		ans = (ans + m * x*B[i]) % mod;
		ans = (ans + mod) % mod;//放在下面以防止溢出(这道题真的会溢出)
	}
	cout << ans << "\n";
}

int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	//freopen("in.txt", "r", stdin);

	init();
	int n;
	cin >> n;
	B.resize(n);
	M.resize(n);
	_for(i, n) cin >> M[i] >> B[i], mod *= M[i];
	Crt(B, M);
	return 0;
}

/*

*/

发布了163 篇原创文章 · 获赞 54 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_42856843/article/details/102636953