列表

详情


NC229006. 【模板】扩展中国剩余定理

描述

给出 个同余方程,求出的最小非负整数解。
若无解则输出"-1"(没有引号)。

输入描述

第一行包含一个正整数,表示同余方程的个数。
接下来行,每行两个正整数
数据保证所有的最小公倍数不超过
注意运算过程中的乘法溢出。

输出描述

输出同余方程的最小非负整数解,若无解输出"-1"(没有引号)。

示例1

输入:

2
8 7
11 9

输出:

31

示例2

输入:

4
11 4
51 4
19 19
81 0

输出:

-1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 112ms, 内存消耗: 1996K, 提交时间: 2023-04-01 10:49:30

#include<bits/stdc++.h>
using namespace std;
#define int long long
int exgcd(int a, int b, int& x, int& y)
{
	if (b == 0)return x = 1, y = 0, a;
	int r = exgcd(b, a % b, x, y);
	tie(x, y) = make_tuple(y, x - a / b * y);
	return r;
}

int excrt(int n, int* r, int* m)
{
	int x = r[1], y1, y2, LCM = m[1];
	for (int i = 2;i<= n;i++)
	{
		int b = m[i], c = ((r[i] - x) % b + b) % b;
		int GCD = exgcd(LCM, b, y1, y2);
		if (c % GCD)return -1;//无解
		y1 = (__int128)y1 * (c / GCD) % (b / GCD);
		x += y1 * LCM;
		LCM *= b / GCD;
		x = (x % LCM + LCM) % LCM;
	}
	return x;
}
const int MAX = 1e5 + 10;
int r[MAX], m[MAX];
signed main()
{
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> m[i] >> r[i];
	cout << excrt(n, r, m) << endl;
}

Python3 解法, 执行用时: 703ms, 内存消耗: 14872K, 提交时间: 2023-05-03 00:55:26

from math import *

def exgcd(a, b):
    if not b:
        return 1, 0, a

    y, x, g = exgcd(b, a % b)
    y = y - a // b * x
    return x, y, g

def excrt(n, r, p):
    now_p = p[0]
    now_r = r[0]

    for i in range(1, n):
        x, y, g = exgcd(now_p, p[i])
        if (r[i] - now_r) % g != 0:
            return -1
        now_r = x * (r[i] - now_r) // g * now_p + now_r
        now_p = lcm(now_p, p[i])
        now_r = now_r % now_p
    return now_r;


n = int(input())
r = []
p = []

for i in range(0, n):
    tmpp, tmpr = map(int, input().split(" "))
    r.append(tmpr)
    p.append(tmpp)

ans = excrt(n, r, p)
print(ans)

C++ 解法, 执行用时: 44ms, 内存消耗: 2048K, 提交时间: 2021-11-29 20:40:52

#include<bits/stdc++.h>

using namespace std;

#define rep(i,a,b) for (int i=(a);i<=(b);i++)
#define LL long long

const int N=100005;

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

LL exgcd(LL a,LL b,LL &x,LL &y)
{
	if (a%b==0) {x=0,y=1;return b;}
	LL d=exgcd(b,a%b,y,x);
	y-=(a/b)*x;return d;
}
int main()
{
	scanf("%d",&n);rep(i,1,n) scanf("%lld%lld",&m[i],&a[i]);
	ans=a[1],M=m[1];rep(i,2,n)
	{
		LL tM,b=a[i]-ans,x,y;
		LL g=exgcd(M,m[i],x,y);
		if (b%g) return puts("-1"),0;
		x=(__int128)x*b/g%m[i]; 
		tM=M,M=M/g*m[i],ans+=(__int128)tM*x%M;
	}
	printf("%lld\n",(ans%M+M)%M);
	return 0;
}

上一题