📌  相关文章
📜  乘积等于两个不同数字之差的子数组的数量

📅  最后修改于: 2021-05-14 01:42:10             🧑  作者: Mango

给定一个非负数组a ,任务是查找子数组的数量,其元素乘积可以表示为两个不同数字的差。
例子:

天真的方法:
上面提到的问题的幼稚解决方案是从给定数组计算所有可能的子数组。然后,我们必须计算每个子数组的乘积。但是这种方法不是很有效并且很费时。
高效的方法:
对上述问题的有效方法的普遍观察是,被2除而不是4的数字在除以4时得到余数2。因此,所有数字都可以表示为两个不同数字的乘积,除了数字当用4取模时得到余数2。为了解决这个问题,我们采用一对向量并将元素与下一个可被2整除的元素的位置一起存储。之后遍历数组并寻找必要的条件如下:

  • 如果遇到奇数,则该数字将形成所有子数组,除非出现一个可被2整除的数字。现在,当另一个数字被2可整除时,该数字也可形成子数组。这两个都存储在对类型向量中。
  • 如果遇到一个可以被4整除的数字,那么这个数字可以构成所有子数组。
  • 如果出现一个只能被2整除的数字,则该数字不能形成子数组,除非出现另一个数字,该数字是2的倍数。

下面是上述方法的实现:

C++
// C++ program to Find count of
// Subarrays whose product can be
// represented as the difference between
// two different numbers
 
#include 
using namespace std;
 
// Function to print number of subarrays
void numberOfSubarrays(int arr[], int n)
{
 
    vector > next(n);
    vector > next_to_next(n);
 
    int f = -1;
    int s = -1;
 
    for (int i = n - 1; i >= 0; i--) {
        next[i].first = arr[i];
 
        next_to_next[i].first = arr[i];
 
        // check if number is divisible by 2
        if (arr[i] % 2 == 0) {
            s = f;
            f = i;
        }
 
        // Store the position
        // of the next element
        next[i].second = f;
 
        // Store the position of
        // next to next element
        // which is multiple of 2
        next_to_next[i].second = s;
    }
 
    int total = 0;
 
    for (int i = 0; i < n; i++) {
        int calculate;
 
        // Check if the element is divisible
        // is divisible by 4
        if (next[i].first % 4 == 0) {
            calculate = n - i;
 
            total += calculate;
        }
 
        // Check if current element
        // is an odd number
        else if (next[i].first & 1 == 1) {
 
            if (next[i].second == -1) {
                calculate = n - i;
 
                total += calculate;
            }
 
            else {
 
                // check if after the current element
                // only 1 element exist which is a
                // multiple of only 2 but not 4
                if (next_to_next[i].second == -1
                 && next[next[i].second].first % 4 != 0)
 
                {
                    calculate = next[i].second - i;
                    total += calculate;
                }
 
                // Check if after the current element an element exist
                // which is multiple of only 2 and not 4 and after that
                // an element also exist which is multiple of 2
                else if (next_to_next[i].second != -1
                         && next[next[i].second].first % 4 != 0) {
                    calculate = n - i;
                    total += calculate;
                    total -= next_to_next[i].second - next[i].second;
                }
 
                // All subarrays can be formed by current element
                else {
                    calculate = n - i;
                    total = total + calculate;
                }
            }
        }
 
        // Condition for an even number
        else {
 
            // Check if next element does not
            // exist which is multiple of 2
            if (next_to_next[i].second == -1)
                total = total;
 
            // Check if next element exist
            // which is multiple of 2
            else {
                calculate = n - i;
                total += calculate;
                total = total - next_to_next[i].second + i;
            }
        }
    }
 
    // Print the output
    cout << total << "\n";
}
 
// Driver Code
int main()
{
    // array initialisation
    int arr[] = { 2, 5, 6 };
 
    int size = sizeof(arr) / sizeof(arr[0]);
 
    numberOfSubarrays(arr, size);
 
    return 0;
}


Java
// Java program to find count of
// subarrays whose product can be
// represented as the difference
// between two different numbers
import java.io.*;
import java.util.*;
 
class GFG{
 
// Function to print number of subarrays
static void numberOfSubarrays(int arr[], int n)
{
    int[][] next = new int[n][2];
    int[][] next_to_next = new int[n][2];
 
    int f = -1;
    int s = -1;
 
    for(int i = n - 1; i >= 0; i--)
    {
        next[i][0] = arr[i];
 
        next_to_next[i][0] = arr[i];
 
        // Check if number is divisible by 2
        if (arr[i] % 2 == 0)
        {
            s = f;
            f = i;
        }
 
        // Store the position
        // of the next element
        next[i][1] = f;
 
        // Store the position of
        // next to next element
        // which is multiple of 2
        next_to_next[i][1] = s;
    }
 
    int total = 0;
 
    for(int i = 0; i < n; i++)
    {
        int calculate;
 
        // Check if the element is divisible
        // is divisible by 4
        if (next[i][0] % 4 == 0)
        {
            calculate = n - i;
            total += calculate;
        }
 
        // Check if current element
        // is an odd number
        else if ((next[i][0] & 1) == 1)
        {
            if (next[i][1] == -1)
            {
                calculate = n - i;
                total += calculate;
            }
 
            else
            {
 
                // Check if after the current element
                // only 1 element exist which is a
                // multiple of only 2 but not 4
                if (next_to_next[i][1] == -1 &&
                    next[next[i][1]][0] % 4 != 0)
                {
                    calculate = next[i][1] - i;
                    total += calculate;
                }
 
                // Check if after the current element
                // an element exist which is multiple
                // of only 2 and not 4 and after that
                // an element also exist which is
                // multiple of 2
                else if (next_to_next[i][1] != -1 &&
                         next[next[i][1]][0] % 4 != 0)
                {
                    calculate = n - i;
                    total += calculate;
                    total -= next_to_next[i][1] -
                                     next[i][1];
                }
 
                // All subarrays can be formed
                // by current element
                else
                {
                    calculate = n - i;
                    total = total + calculate;
                }
            }
        }
 
        // Condition for an even number
        else
        {
             
            // Check if next element does not
            // exist which is multiple of 2
            if (next_to_next[i][1] == -1)
                total = total;
 
            // Check if next element exist
            // which is multiple of 2
            else
            {
                calculate = n - i;
                total += calculate;
                total = total - next_to_next[i][1] + i;
            }
        }
    }
 
    // Print the output
    System.out.println(total);
}
 
// Driver Code
public static void main(String args[])
{
     
    // Array initialisation
    int arr[] = { 2, 5, 6 };
 
    int size = arr.length;
 
    numberOfSubarrays(arr, size);
}
}
 
// This code is contributed by offbeat


Python3
# Python program to find count of
# subarrays whose product can be
# represented as the difference
# between two different numbers
 
# Function to print number of subarrays
def numberOfSubarrays(arr, n):
 
    Next = [[0 for i in range(2)] for j in range(n)]
    next_to_next = [[0 for i in range(2)] for j in range(n)]
 
    f = -1
    s = -1
 
    for i in range(n - 1, -1, -1) :
     
        Next[i][0] = arr[i]
 
        next_to_next[i][0] = arr[i]
 
        # Check if number is divisible by 2
        if (arr[i] % 2 == 0) :
     
            s = f
            f = i
 
        # Store the position
        # of the next element
        Next[i][1] = f
 
        # Store the position of
        # next to next element
        # which is multiple of 2
        next_to_next[i][1] = s
 
    total = 0
 
    for i in range(n) :
 
        calculate = 0
 
        # Check if the element is divisible
        # is divisible by 4
        if (Next[i][0] % 4 == 0) :
         
            calculate = n - i
            total += calculate
 
        # Check if current element
        # is an odd number
        elif ((Next[i][0] & 1) == 1) :
         
            if (Next[i][1] == -1) :
              
                calculate = n - i
                total += calculate
 
            else :
             
                # Check if after the current element
                # only 1 element exist which is a
                # multiple of only 2 but not 4
                if (next_to_next[i][1] == -1 and Next[Next[i][1]][0] % 4 != 0) :
             
                    calculate = Next[i][1] - i
                    total += calculate
 
                # Check if after the current element
                # an element exist which is multiple
                # of only 2 and not 4 and after that
                # an element also exist which is
                # multiple of 2
                elif (next_to_next[i][1] != -1 and Next[Next[i][1]][0] % 4 != 0) :
                 
                    calculate = n - i
                    total += calculate
                    total -= next_to_next[i][1] - Next[i][1]
 
                # All subarrays can be formed
                # by current element
                else :
                 
                    calculate = n - i
                    total = total + calculate
 
        # Condition for an even number
        else :
             
            # Check if next element does not
            # exist which is multiple of 2
            if (next_to_next[i][1] == -1) :
                total = total
 
            # Check if next element exist
            # which is multiple of 2
            else :
 
                calculate = n - i
                total += calculate
                total = total - next_to_next[i][1] + i
 
    # Print the output
    print(total)
 
# Array initialisation
arr = [ 2, 5, 6 ]
 
size = len(arr)
 
numberOfSubarrays(arr, size)
 
# This code is contributed by divyesh072019


C#
// C# program to find count of 
// subarrays whose product can be 
// represented as the difference 
// between two different numbers 
using System;
class GFG{
     
// Function to print number
// of subarrays 
static void numberOfSubarrays(int[] arr,
                              int n) 
{ 
  int[,] next = new int[n, 2]; 
  int[,] next_to_next = new int[n, 2];
  int f = -1; 
  int s = -1; 
 
  for(int i = n - 1; i >= 0; i--)
  { 
    next[i, 0] = arr[i]; 
    next_to_next[i, 0] = arr[i]; 
 
    // Check if number is
    // divisible by 2 
    if (arr[i] % 2 == 0)
    { 
      s = f; 
      f = i; 
    } 
 
    // Store the position 
    // of the next element 
    next[i, 1] = f; 
 
    // Store the position of 
    // next to next element 
    // which is multiple of 2 
    next_to_next[i, 1] = s; 
  } 
 
  int total = 0; 
 
  for(int i = 0; i < n; i++)
  { 
    int calculate; 
 
    // Check if the element is
    // divisible is divisible by 4 
    if (next[i, 0] % 4 == 0) 
    { 
      calculate = n - i; 
      total += calculate; 
    } 
 
    // Check if current element 
    // is an odd number 
    else if ((next[i, 0] & 1) == 1)
    { 
      if (next[i, 1] == -1) 
      { 
        calculate = n - i; 
        total += calculate; 
      } 
      else
      {
        // Check if after the current element 
        // only 1 element exist which is a 
        // multiple of only 2 but not 4 
        if (next_to_next[i, 1] == -1 && 
            next[next[i, 1], 0] % 4 != 0) 
        { 
          calculate = next[i, 1] - i; 
          total += calculate; 
        } 
 
        // Check if after the current element
        // an element exist which is multiple
        // of only 2 and not 4 and after that 
        // an element also exist which is 
        // multiple of 2 
        else if (next_to_next[i, 1] != -1 &&
                 next[next[i, 1], 0] % 4 != 0)
        { 
          calculate = n - i; 
          total += calculate; 
          total -= next_to_next[i, 1] - 
            next[i, 1]; 
        } 
 
        // All subarrays can be formed
        // by current element 
        else
        { 
          calculate = n - i; 
          total = total + calculate; 
        } 
      } 
    } 
 
    // Condition for an even number 
    else
    { 
      // Check if next element does not 
      // exist which is multiple of 2 
      if (next_to_next[i, 1] == -1)
      {
        //total = total;
      }
       
      // Check if next element exist 
      // which is multiple of 2 
      else
      { 
        calculate = n - i; 
        total += calculate; 
        total = total -
                next_to_next[i, 1] + i; 
      } 
    } 
  } 
 
  // Print the output 
  Console.WriteLine(total); 
} 
 
static void Main()
{
 
  // Array initialisation 
  int[] arr = {2, 5, 6}; 
 
  int size = arr.Length; 
 
  numberOfSubarrays(arr, size); 
}
}
 
// This code is contributed by divyeshrabadiya07


Javascript


输出:
2

时间复杂度: O(N)