📌  相关文章
📜  用于数组中范围产品的 Python3 程序

📅  最后修改于: 2022-05-13 01:55:31.001000             🧑  作者: Mango

用于数组中范围产品的 Python3 程序

给定一个大小为 N 的数组 A[]。解决 Q 个查询。在模 P 下找到范围 [L, R] 中的产品(P 是素数)。

例子:

Input : A[] = {1, 2, 3, 4, 5, 6} 
          L = 2, R = 5, P = 229
Output : 120

Input : A[] = {1, 2, 3, 4, 5, 6},
         L = 2, R = 5, P = 113
Output : 7 

蛮力
对于每个查询,遍历 [L, R] 范围内的每个元素并计算模 P 下的乘积。这将在 O(N) 中回答每个查询。

Python3
# Python3 program to find
# Product in range Queries in O(N)
 
# Function to calculate Product
# in the given range.
def calculateProduct (A, L, R, P):
 
    # As our array is 0 based 
    # and L and R are given as
    # 1 based index.
    L = L - 1
    R = R - 1
    ans = 1
    for i in range(R + 1):
        ans = ans * A[i]
        ans = ans % P
    return ans
     
# Driver code
A = [ 1, 2, 3, 4, 5, 6 ]
P = 229
L = 2
R = 5
print (calculateProduct(A, L, R, P))
L = 1
R = 3
print (calculateProduct(A, L, R, P))
 
# This code is contributed
# by "Abhishek Sharma 44"


Python3
# Python3 implementation of the
# above approach
 
# Returns modulo inverse of a with
# respect to m using extended Euclid
# Algorithm. Assumption: a and m are
# coprimes, i.e., gcd(a, m) = 1
def modInverse(a, m):
 
    m0, x0, x1 = m, 0, 1
 
    if m == 1:
        return 0
 
    while a > 1:
 
        # q is quotient
        q = a // m
        t = m
 
        # m is remainder now, process
        # same as Euclid's algo
        m, a = a % m, t
        t = x0
        x0 = x1 - q * x0
        x1 = t
 
    # Make x1 positive
    if x1 < 0:
        x1 += m0
 
    return x1
 
# calculating pre_product array
def calculate_Pre_Product(A, N, P):
 
    pre_product[0] = A[0]
 
    for i in range(1, N):
     
        pre_product[i] = pre_product[i - 1] * A[i]
        pre_product[i] = pre_product[i] % P
 
# Calculating inverse_product
# array.
def calculate_inverse_product(A, N, P):
 
    inverse_product[0] = modInverse(pre_product[0], P)
 
    for i in range(1, N):
        inverse_product[i] = modInverse(pre_product[i], P)
 
# Function to calculate
# Product in the given range.
def calculateProduct(A, L, R, P):
 
    # As our array is 0 based as
    # and L and R are given as 1
    # based index.
    L = L - 1
    R = R - 1
    ans = 0
 
    if L == 0:
        ans = pre_product[R]
    else:
        ans = pre_product[R] * inverse_product[L - 1]
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    # Array
    A = [1, 2, 3, 4, 5, 6]
    N = len(A)
 
    # Prime P
    P = 113
    MAX = 100
     
    pre_product = [None] * (MAX)
    inverse_product = [None] * (MAX)
 
    # Calculating PreProduct
    # and InverseProduct
    calculate_Pre_Product(A, N, P)
    calculate_inverse_product(A, N, P)
 
    # Range [L, R] in 1 base index
    L, R = 2, 5
    print(calculateProduct(A, L, R, P))
 
    L, R = 1, 3
    print(calculateProduct(A, L, R, P))
     
# This code is contributed by Rituraj Jain


输出 :

120
6

高效使用模乘逆:
由于 P 是素数,我们可以使用模乘逆。使用动态规划,我们可以计算模 P 下的前积数组,使得索引 i 处的值包含 [0, i] 范围内的乘积。类似地,我们可以计算模 P 下的预逆积。现在每个查询都可以在 O(1) 中得到回答。
逆积数组包含索引 i 处 [0, i] 范围内的逆积。因此,对于查询 [L, R],答案将是 Product[R]*InverseProduct[L-1]
注意:我们不能将答案计算为 Product[R]/Product[L-1],因为乘积是在模 P 下计算的。如果我们不计算模 P 下的乘积,总是有溢出的可能性。

Python3

# Python3 implementation of the
# above approach
 
# Returns modulo inverse of a with
# respect to m using extended Euclid
# Algorithm. Assumption: a and m are
# coprimes, i.e., gcd(a, m) = 1
def modInverse(a, m):
 
    m0, x0, x1 = m, 0, 1
 
    if m == 1:
        return 0
 
    while a > 1:
 
        # q is quotient
        q = a // m
        t = m
 
        # m is remainder now, process
        # same as Euclid's algo
        m, a = a % m, t
        t = x0
        x0 = x1 - q * x0
        x1 = t
 
    # Make x1 positive
    if x1 < 0:
        x1 += m0
 
    return x1
 
# calculating pre_product array
def calculate_Pre_Product(A, N, P):
 
    pre_product[0] = A[0]
 
    for i in range(1, N):
     
        pre_product[i] = pre_product[i - 1] * A[i]
        pre_product[i] = pre_product[i] % P
 
# Calculating inverse_product
# array.
def calculate_inverse_product(A, N, P):
 
    inverse_product[0] = modInverse(pre_product[0], P)
 
    for i in range(1, N):
        inverse_product[i] = modInverse(pre_product[i], P)
 
# Function to calculate
# Product in the given range.
def calculateProduct(A, L, R, P):
 
    # As our array is 0 based as
    # and L and R are given as 1
    # based index.
    L = L - 1
    R = R - 1
    ans = 0
 
    if L == 0:
        ans = pre_product[R]
    else:
        ans = pre_product[R] * inverse_product[L - 1]
 
    return ans
 
# Driver Code
if __name__ == "__main__":
 
    # Array
    A = [1, 2, 3, 4, 5, 6]
    N = len(A)
 
    # Prime P
    P = 113
    MAX = 100
     
    pre_product = [None] * (MAX)
    inverse_product = [None] * (MAX)
 
    # Calculating PreProduct
    # and InverseProduct
    calculate_Pre_Product(A, N, P)
    calculate_inverse_product(A, N, P)
 
    # Range [L, R] in 1 base index
    L, R = 2, 5
    print(calculateProduct(A, L, R, P))
 
    L, R = 1, 3
    print(calculateProduct(A, L, R, P))
     
# This code is contributed by Rituraj Jain

输出 :

7
6

有关更多详细信息,请参阅有关数组范围产品的完整文章!