数组中范围乘积的Java程序
给定一个大小为 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) 中的每个查询。
Java
// Product in range Queries in O(N)
import java.io.*;
class GFG
{
// Function to calculate
// Product in the given range.
static int calculateProduct(int []A, int L,
int R, int P)
{
// As our array is 0 based as
// and L and R are given as 1
// based index.
L = L - 1;
R = R - 1;
int ans = 1;
for (int i = L; i <= R; i++)
{
ans = ans * A[i];
ans = ans % P;
}
return ans;
}
// Driver code
static public void main (String[] args)
{
int []A = { 1, 2, 3, 4, 5, 6 };
int P = 229;
int L = 2, R = 5;
System.out.println(
calculateProduct(A, L, R, P));
L = 1;
R = 3;
System.out.println(
calculateProduct(A, L, R, P));
}
}
// This code is contributed by vt_m.
Java
// Java program to find Product
// in range Queries in O(1)
class GFG
{
static int MAX = 100;
int pre_product[] = new int[MAX];
int inverse_product[] = new int[MAX];
// 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
int modInverse(int a, int m)
{
int m0 = m, t, q;
int x0 = 0, x1 = 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 % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
// Make x1 positive
if (x1 < 0)
x1 += m0;
return x1;
}
// calculating pre_product array
void calculate_Pre_Product(int A[],
int N, int P)
{
pre_product[0] = A[0];
for (int i = 1; i < N; i++)
{
pre_product[i] = pre_product[i - 1] *
A[i];
pre_product[i] = pre_product[i] % P;
}
}
// Calculating inverse_product array.
void calculate_inverse_product(int A[],
int N, int P)
{
inverse_product[0] = modInverse(pre_product[0],
P);
for (int i = 1; i < N; i++)
inverse_product[i] = modInverse(pre_product[i],
P);
}
// Function to calculate Product
// in the given range.
int calculateProduct(int A[], int L,
int R, int P)
{
// As our array is 0 based as and
// L and R are given as 1 based index.
L = L - 1;
R = R - 1;
int ans;
if (L == 0)
ans = pre_product[R];
else
ans = pre_product[R] *
inverse_product[L - 1];
return ans;
}
// Driver code
public static void main(String[] s)
{
GFG d = new GFG();
// Array
int A[] = { 1, 2, 3, 4, 5, 6 };
// Prime P
int P = 113;
// Calculating PreProduct and
// InverseProduct
d.calculate_Pre_Product(A, A.length, P);
d.calculate_inverse_product(A, A.length,
P);
// Range [L, R] in 1 base index
int L = 2, R = 5;
System.out.println(d.calculateProduct(A, L,
R, P));
L = 1;
R = 3;
System.out.println(d.calculateProduct(A, L,
R, P));
}
}
// This code is contributed by Prerna Saini
输出 :
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 下的乘积,总是有溢出的可能性。
Java
// Java program to find Product
// in range Queries in O(1)
class GFG
{
static int MAX = 100;
int pre_product[] = new int[MAX];
int inverse_product[] = new int[MAX];
// 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
int modInverse(int a, int m)
{
int m0 = m, t, q;
int x0 = 0, x1 = 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 % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
// Make x1 positive
if (x1 < 0)
x1 += m0;
return x1;
}
// calculating pre_product array
void calculate_Pre_Product(int A[],
int N, int P)
{
pre_product[0] = A[0];
for (int i = 1; i < N; i++)
{
pre_product[i] = pre_product[i - 1] *
A[i];
pre_product[i] = pre_product[i] % P;
}
}
// Calculating inverse_product array.
void calculate_inverse_product(int A[],
int N, int P)
{
inverse_product[0] = modInverse(pre_product[0],
P);
for (int i = 1; i < N; i++)
inverse_product[i] = modInverse(pre_product[i],
P);
}
// Function to calculate Product
// in the given range.
int calculateProduct(int A[], int L,
int R, int P)
{
// As our array is 0 based as and
// L and R are given as 1 based index.
L = L - 1;
R = R - 1;
int ans;
if (L == 0)
ans = pre_product[R];
else
ans = pre_product[R] *
inverse_product[L - 1];
return ans;
}
// Driver code
public static void main(String[] s)
{
GFG d = new GFG();
// Array
int A[] = { 1, 2, 3, 4, 5, 6 };
// Prime P
int P = 113;
// Calculating PreProduct and
// InverseProduct
d.calculate_Pre_Product(A, A.length, P);
d.calculate_inverse_product(A, A.length,
P);
// Range [L, R] in 1 base index
int L = 2, R = 5;
System.out.println(d.calculateProduct(A, L,
R, P));
L = 1;
R = 3;
System.out.println(d.calculateProduct(A, L,
R, P));
}
}
// This code is contributed by Prerna Saini
输出 :
7
6
有关更多详细信息,请参阅有关数组范围产品的完整文章!