📅  最后修改于: 2023-12-03 14:53:38.563000             🧑  作者: Mango
题目描述:给定两个长度为n的数组A和B,找到一个最小的非负整数X,使得对于所有的i(0<=i<n),都满足X%A[i]=B[i]。
这是一道比较简单的数学题,根据题目描述,我们可以列出如下的等式:
X % A[0] = B[0] X % A[1] = B[1] ... X % A[n-1] = B[n-1]
我们可以把这些等式合并成一个大的等式:
X % A[0] = B[0] (X % A[1] - B[1]) % A[1] = 0 ... (X % A[n-1] - B[n-1]) % A[n-1] = 0
注意到第二个等式中的(X % A[1] - B[1]) % A[1] = 0,这说明X % A[1] = B[1]。我们可以把它代入第三个等式,得到(X % A[2] - B[2] + A[2] * k) % A[2] = 0,其中k是一个整数。
不断地代入等式,我们可以得到如下的等式:
X % A[0] = B[0] X % A[1] = B[1] X % A[2] = B[2] ... X % A[n-1] = B[n-1]
解这个方程组,我们可以得到一个X满足条件X % A[i] = B[i]。而根据中国剩余定理,我们可以把这个方程组转化成一个模数为A[0] * A[1] * ... * A[n-1]的同余方程组。因此,我们可以先求出所有A[i]的最小公倍数LCM,然后求出X在模LCM意义下的最小非负整数解即可。
def solve(A, B):
LCM = 1
for a in A:
LCM *= a
X = 0
for i in range(len(A)):
m = LCM // A[i]
r = pow(m, A[i]-2, A[i]) * B[i] % A[i] # 用费马小定理求逆元
X = (X + m * r) % LCM
return X
本算法只需要遍历一遍数组A和数组B,时间复杂度为O(n),计算逆元的时间复杂度为O(logA[i]),因此总的时间复杂度为O(nlogA[i])。而由于A数组中所有数字的乘积不会超过2^63-1,因此本算法是正确的。