📌  相关文章
📜  查询给定数组中所有数字的GCD(给定范围内的元素除外)

📅  最后修改于: 2021-04-27 20:42:32             🧑  作者: Mango

给定一个由n个数字组成的数组,并给出了多个查询。每个查询将由两个整数l,r表示。任务是找出每个查询的数组中所有数字的GCD,但不包括范围l,r(包括两端)中给出的数字。
例子:

Input : arr[] = {2, 6, 9}
        Ranges [0 0], [1 1], [1 2]
Output : 3
         1
         2 
GCD of numbers excluding [0 0] or 
first element is GCD(6, 9) = 3
GCD of numbers excluding the [1 1] or
second element is GCD(2, 9) = 1
GCD of numbers excluding [1 2] is 
equal to first element = 2

注意:我们在下面的说明中使用基于1的索引
我们从一个非常基本的问题开始,如何计算两个数字的GCD,最好的选择是Euclid算法。现在,如何计算多个数字的GCD,简单地假设存在三个数字a,b和c,则解决方案很简单。 GCD(a,b,c)= GCD(GCD(a,b),c)。这样,我们可以轻松找出任意数量的GCD。
解决每个查询问题的一种简单方法是假设给定的范围是l和r。假设从1到l-1的数字的GCD为x,然后从r + 1到n范围的数字的GCD为y,则每个查询的输出将为GCD(x,y)。
一种有效的解决方案是使用两个数组,一个作为前缀数组,第二个作为后缀数组。前缀数组的第i个索引将存储从1到i的数字的GCD,后缀数组的第i个索引将表示从i到n的数字的GCD。现在假设给定的特定查询范围是l,r,很明显该查询的输出将是GCD(prefix [l-1],suffix [r + 1])。

C++
// C++ program for queries of GCD excluding
// given range of elements.
#include
using namespace std;
 
 
// Filling the prefix and suffix array
void FillPrefixSuffix(int prefix[], int arr[],
                           int suffix[], int n)
{
    // Filling the prefix array following relation
    // prefix(i) = __gcd(prefix(i-1), arr(i))
    prefix[0] = arr[0];
    for (int i=1 ;i=0 ;i--)
        suffix[i] = __gcd(suffix[i+1], arr[i]);
}
 
// To calculate gcd of the numbers outside range
int GCDoutsideRange(int l, int r, int prefix[],
                           int suffix[], int n)
{
    // If l=0, we need to tell GCD of numbers
    // from r+1 to n
    if (l==0)
        return suffix[r+1];
 
    // If r=n-1 we need to return the gcd of
    // numbers from 1 to l
    if (r==n-1)
        return prefix[l-1];
    return __gcd(prefix[l-1], suffix[r+1]);
}
 
// Driver function
int main()
{
    int arr[] = {2, 6, 9};
    int n = sizeof(arr)/sizeof(arr[0]);
    int prefix[n], suffix[n];
    FillPrefixSuffix(prefix, arr, suffix, n);
 
    int l = 0, r = 0;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    l = 1 ; r = 1;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    l = 1 ; r = 2;
    cout << GCDoutsideRange(l, r, prefix, suffix, n)
         << endl;
    return 0;
}


Java
// Java program for queries of GCD excluding
// given range of elements.
import java.util.*;
 
class GFG {
     
// Calculating GCD using euclid algorithm
static int GCD(int a, int b)
{
    if (b == 0)
    return a;
    return GCD(b, a % b);
}
 
// Filling the prefix and suffix array
static void FillPrefixSuffix(int prefix[],
          int arr[], int suffix[], int n)
{
    // Filling the prefix array following relation
    // prefix(i) = GCD(prefix(i-1), arr(i))
    prefix[0] = arr[0];
    for (int i = 1; i < n; i++)
    prefix[i] = GCD(prefix[i - 1], arr[i]);
 
    // Filling the suffix array following the
    // relation suffix(i) = GCD(suffix(i+1), arr(i))
    suffix[n - 1] = arr[n - 1];
 
    for (int i = n - 2; i >= 0; i--)
    suffix[i] = GCD(suffix[i + 1], arr[i]);
}
 
// To calculate gcd of the numbers outside range
static int GCDoutsideRange(int l, int r,
      int prefix[], int suffix[], int n) {
           
    // If l=0, we need to tell GCD of numbers
    // from r+1 to n
    if (l == 0)
    return suffix[r + 1];
 
    // If r=n-1 we need to return the gcd of
    // numbers from 1 to l
    if (r == n - 1)
    return prefix[l - 1];
    return GCD(prefix[l - 1], suffix[r + 1]);
}
 
// Driver code
public static void main(String[] args) {
    int arr[] = {2, 6, 9};
    int n = arr.length;
    int prefix[] = new int[n];
    int suffix[] = new int[n];
    FillPrefixSuffix(prefix, arr, suffix, n);
 
    int l = 0, r = 0;
    System.out.println(GCDoutsideRange
             (l, r, prefix, suffix, n));
 
    l = 1;
    r = 1;
    System.out.println(GCDoutsideRange
             (l, r, prefix, suffix, n));
 
    l = 1;
    r = 2;
    System.out.println(GCDoutsideRange
             (l, r, prefix, suffix, n));
}
}
 
// This code is contributed by Anant Agarwal.


Python3
# Python program for
# queries of GCD excluding
# given range of elements.
 
# Calculating GCD
# using euclid algorithm
def GCD(a,b):
    if (b==0):
        return a
    return GCD (b, a%b)
 
  
# Filling the prefix
# and suffix array
def FillPrefixSuffix(prefix,arr,suffix,n):
 
    # Filling the prefix array
    # following relation
    # prefix(i) = GCD(prefix(i-1), arr(i))
    prefix[0] = arr[0]
    for i in range(1,n):
        prefix[i] = GCD (prefix[i-1], arr[i])
  
    # Filling the suffix
    # array following the
    # relation suffix(i) = GCD(suffix(i+1), arr(i))
    suffix[n-1] = arr[n-1]
  
    for i in range(n-2,-1,-1):
        suffix[i] = GCD (suffix[i+1], arr[i])
 
  
# To calculate gcd of
# the numbers outside range
def GCDoutsideRange(l,r,prefix,suffix,n):
     
    # If l=0, we need to tell GCD of numbers
    # from r+1 to n
    if (l==0):
        return suffix[r+1]
  
    # If r=n-1 we need to return the gcd of
    # numbers from 1 to l
    if (r==n-1):
        return prefix[l-1]
    return GCD(prefix[l-1], suffix[r+1])
 
# Driver code
 
arr = [2, 6, 9]
n = len(arr)
prefix=[]
suffix=[]
for i in range(n+1):
    prefix.append(0)
    suffix.append(0)
     
FillPrefixSuffix(prefix, arr, suffix, n)
l = 0
r = 0
print(GCDoutsideRange(l, r, prefix, suffix, n))
 
l = 1
r = 1
print(GCDoutsideRange(l, r, prefix, suffix, n))
 
l = 1
r = 2
print(GCDoutsideRange(l, r, prefix, suffix, n))
 
# This code is contributed
# by Anant Agarwal.


C#
// C# program for queries of GCD
// excluding given range of elements.
using System;
 
class GFG {
     
// Calculating GCD using
// euclid algorithm
static int GCD(int a, int b)
{
    if (b == 0)
    return a;
    return GCD(b, a % b);
}
 
// Filling the prefix and suffix array
static void FillPrefixSuffix(int []prefix,
                             int []arr,
                             int []suffix,
                             int n)
{
     
    // Filling the prefix array following
    // relation prefix(i) =
    // GCD(prefix(i - 1), arr(i))
    prefix[0] = arr[0];
    for (int i = 1; i < n; i++)
    prefix[i] = GCD(prefix[i - 1], arr[i]);
 
    // Filling the suffix array following
    // the relation suffix(i) =
    // GCD(suffix(i+1), arr(i))
    suffix[n - 1] = arr[n - 1];
 
    for (int i = n - 2; i >= 0; i--)
    suffix[i] = GCD(suffix[i + 1], arr[i]);
}
 
// To calculate gcd of the numbers outside range
static int GCDoutsideRange(int l, int r,
                           int []prefix,
                           int []suffix,
                           int n)
    {
             
    // If l=0, we need to tell
    // GCD of numbers from r+1 to n
    if (l == 0)
    return suffix[r + 1];
 
    // If r=n-1 we need to return the
    // gcd of numbers from 1 to l
    if (r == n - 1)
    return prefix[l - 1];
    return GCD(prefix[l - 1], suffix[r + 1]);
}
 
// Driver Code
public static void Main()
{
    int []arr = {2, 6, 9};
    int n = arr.Length;
    int []prefix = new int[n];
    int []suffix = new int[n];
    FillPrefixSuffix(prefix, arr, suffix, n);
 
    int l = 0, r = 0;
    Console.WriteLine(GCDoutsideRange
                     (l, r, prefix, suffix, n));
  
    l = 1;
    r = 1;
    Console.WriteLine(GCDoutsideRange
                        (l, r, prefix, suffix, n));
 
    l = 1;
    r = 2;
    Console.Write(GCDoutsideRange
                 (l, r, prefix, suffix, n));
}
}
 
// This code is contributed by Nitin Mittal.


PHP
= 0 ;$i--)
        $suffix[$i] = GCD ($suffix[$i + 1], $arr[$i]);
}
 
// To calculate gcd of the numbers outside range
function GCDoutsideRange($l, $r, &$prefix, &$suffix, $n)
{
    // If l=0, we need to tell GCD of numbers
    // from r+1 to n
    if ($l == 0)
        return $suffix[$r + 1];
 
    // If r=n-1 we need to return the gcd of
    // numbers from 1 to l
    if ($r == $n - 1)
        return $prefix[$l - 1];
    return GCD($prefix[$l - 1], $suffix[$r + 1]);
}
 
// Driver Code
$arr = array(2, 6, 9);
$n = sizeof($arr);
$prefix = array_fill(0, $n, NULL);
$suffix = array_fill(0, $n, NULL);
FillPrefixSuffix($prefix, $arr, $suffix, $n);
 
$l = 0;
$r = 0;
echo GCDoutsideRange($l, $r, $prefix, $suffix, $n) . "\n";
$l = 1 ;
$r = 1;
echo GCDoutsideRange($l, $r, $prefix, $suffix, $n) . "\n";
$l = 1 ;
$r = 2;
echo GCDoutsideRange($l, $r, $prefix, $suffix, $n) . "\n";
 
// This code is contributed by ita_c
?>


Javascript


输出:

3
1
2