📌  相关文章
📜  其乘积没有任何重复素因子的子数组的计数

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

其乘积没有任何重复素因子的子数组的计数

给定一个整数数组。在结果数的素数分解中找出所有元素的乘积不包含重复素数因子的子数组的总数。
例子:

Input: 2 3 9
Output: 3
Explanation:
Total sub-array are:-
{2}, {3}, {9}, {2, 3}, {3, 9}, {2, 3, 9}

Subarray which violets the property are:-
{9}       -> {3 * 3}, Since 3 is a repeating prime
             factor in prime decomposition of 9
{3, 9}    -> {3 * 3 * 3}, 3 is a repeating prime 
             factor in prime decomposition of 27
{2, 3, 9} -> {2 * 3 * 3 * 3}, 3 is repeating 
             prime factor in prime decomposition 
             of 54
Hence total subarray remains which satisfies our
condition are 3.

Input: 2, 3, 5, 15, 7, 2
Output: 12

一种天真的方法是在另一个内部运行一个循环并生成所有子数组,然后取所有元素的乘积,这样它的主要分解不包含重复元素。这种方法肯定会很慢,并且会导致数组元素的大值溢出。
一种有效的方法是使用埃拉托色尼筛法进行素数分解。

  1. ind[]是一个数组,使得 ind[i] 将质数除数 i 的最后一个索引存储在 arr[] 中,并且“last_ind”跟踪任何除数的最后一个索引。
  2. 现在从左到右(0 到 n-1)遍历。对于 array[i] 的特定元素,使用上述方法找到素数除数,并使用最新索引'i+1'初始化所有除数。
  3. 但在执行第 2 步之前,我们用 array[i] 的每个除数的 ind[] 更新“last_ind”的变量。
  4. 由于变量 'last_ind' 包含数组 [i] 的任何除数的最后一个索引(小于 i),我们可以确保所有元素(last_ind+1,last_ind+2 ... i)不会有任何重复的 arr 素数因子[一世]。因此我们的 ans 将是(i – last_ind +1)
  5. 对 array[] 的剩余元素执行上述步骤,同时更新每个索引的答案。
C++
// C++ program to count all sub-arrays whose
// product doesn't contain a repeating prime
// factor.
#include
using namespace std;
 
const int MAXN = 1000001;
int spf[MAXN];
 
// Calculating SPF (Smallest Prime Factor) for
// every number till MAXN.
// Time Complexity : O(n log log n)
void sieve()
{
    // marking smallest prime factor for every
    // number to be itself.
    for (int i=1; i 1)
        {
            int div = spf[arr[i]];
 
            // Fetch the last index of prime
            // divisor of element
            last_ind = max(last_ind, ind[div]);
 
            // Update the current divisor index
            ind[div] = i + 1;
 
            arr[i] /= div;
        }
 
        // Update result, we basically include
        // all required subarrays ending with
        // index arr[i].
        count += i - last_ind + 1;
    }
    return count;
}
 
// Driver code
int main()
{
    sieve();
    int arr[] = {2, 3, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << countSubArray(arr, n) << "\n";
 
    int arr1[] = {2, 3, 5, 15, 7, 2};
    int n1 = sizeof(arr1) / sizeof(arr1[0]);
    cout << countSubArray(arr1, n1);
 
    return 0;
}


Java
// Java program to count all sub-arrays whose
// product doesn't contain a repeating prime
// factor
import java.io.*;
import java.util.*;
 
class GFG
{
    public static int MAXN = 1000001;
    public static int[] spf = new int[MAXN];
     
    // Calculating SPF (Smallest Prime Factor) for
    // every number till MAXN.
    // Time Complexity : O(n log log n)
    static void sieve()
    {
        // marking smallest prime factor for every
        // number to be itself.
        for (int i=1; i 1)
            {
                int div = spf[arr[i]];
  
                // Fetch the last index of prime
                // divisor of element
                last_ind = Math.max(last_ind, ind[div]);
  
                // Update the current divisor index
                ind[div] = i + 1;
  
                arr[i] /= div;
            }
  
            // Update result, we basically include
            // all required subarrays ending with
            // index arr[i].
            count += i - last_ind + 1;
        }
        return count;
    }
     
    // driver program
    public static void main (String[] args)
    {
        sieve();
        int arr[] = {2, 3, 9};
        int n = arr.length;
        System.out.println(countSubArray(arr, n));
         
        int arr1[] = {2, 3, 5, 15, 7, 2};
        int n1 = arr1.length;
        System.out.println(countSubArray(arr1, n1));
    }
}
 
// Contributed by Pramod Kumar


Python3
# Python 3 program to count all sub-arrays
# whose product does not contain a repeating
# prime factor.
from math import sqrt
 
MAXN = 1000001
spf = [0 for i in range(MAXN)]
 
# Calculating SPF (Smallest Prime Factor)
# for every number till MAXN.
# Time Complexity : O(n log log n)
def sieve():
     
    # marking smallest prime factor
    # for every number to be itself.
    for i in range(1, MAXN, 1):
        spf[i] = i
 
    # separately marking spf for
    # every even number as 2
    for i in range(4, MAXN, 2):
        spf[i] = 2
     
    k = int(sqrt(MAXN))
    for i in range(3, k, 1):
         
        # checking if i is prime
        if (spf[i] == i):
             
            # marking SPF for all numbers
            # divisible by i
            for j in range(i * i, MAXN, i):
                 
                # marking spf[j] if it is
                # not previously marked
                if (spf[j] == j):
                    spf[j] = i
 
# Function to count all sub-arrays whose
# product doesn't contain a repeating
# prime factor.
def countSubArray(arr, n):
     
    # ind[i] is going to store 1 + last
    # index of an array element which
    # has i as prime factor.
    ind = [-1 for i in range(MAXN)]
 
    count = 0
     
    # Initialize result
    last_ind = 0
     
    # It stores index
    for i in range(0, n, 1):
        while (arr[i] > 1):
            div = spf[arr[i]]
 
            # Fetch the last index of prime
            # divisor of element
            last_ind = max(last_ind, ind[div])
 
            # Update the current divisor index
            ind[div] = i + 1
 
            arr[i] = int(arr[i] / div)
             
        # Update result, we basically include
        # all required subarrays ending with
        # index arr[i].
        count += i - last_ind + 1
    return count
 
# Driver code
if __name__ == '__main__':
    sieve()
    arr = [2, 3, 9]
    n = len(arr)
    print(countSubArray(arr, n))
 
    arr1 = [2, 3, 5, 15, 7, 2]
    n1 = len(arr1)
    print(countSubArray(arr1, n1))
 
# This code is contributed by
# Shashank_Sharma


C#
// C# program to count all sub-arrays
// whose product doesn't contain a
// repeating prime factor
using System;
         
public class GFG  {
     
    public static int MAXN = 1000001;
    public static int[] spf = new int[MAXN];
     
    // Calculating SPF (Smallest Prime Factor)
    // for every number till MAXN.
    // Time Complexity : O(n log log n)
    static void sieve()
    {
        // marking smallest prime factor
        // for every number to be itself.
        for (int i = 1; i < MAXN; i++)
            spf[i] = i;
 
        // separately marking spf for
        // every even number as 2
        for (int i = 4; i < MAXN; i += 2)
            spf[i] = 2;
 
        for (int i = 3; i * i < MAXN; i++)
        {
            // checking if i is prime
            if (spf[i] == i)
            {
                // marking SPF for all numbers divisible
                // by i
                for (int j = i * i; j < MAXN; j += i)
 
                    // marking spf[j] if it is
                    // not previously marked
                    if (spf[j] == j)
                        spf[j] = i;
            }
        }
    }
     
    // Function to count all sub-arrays
    // whose product doesn't contain
    // a repeating prime factor
    static int countSubArray(int []arr, int n)
    {
         
        // ind[i] is going to store 1 + last
        // index of an array element which
        // has i as prime factor.
        int[] ind = new int[MAXN];
         
        for(int i = 0; i < MAXN; i++)
        {
            ind[i] = -1;
        }
         
         
        int count = 0; // Initialize result
        int last_ind = 0; // It stores index
        for (int i = 0; i < n; ++i)
        {
            while (arr[i] > 1)
            {
                int div = spf[arr[i]];
 
                // Fetch the last index of prime
                // divisor of element
                last_ind = Math.Max(last_ind, ind[div]);
 
                // Update the current divisor index
                ind[div] = i + 1;
 
                arr[i] /= div;
            }
 
            // Update result, we basically include
            // all required subarrays ending with
            // index arr[i].
            count += i - last_ind + 1;
        }
        return count;
    }
     
    // Driver Code
    public static void Main ()
    {
        sieve();
        int []arr = {2, 3, 9};
        int n = arr.Length;
        Console.WriteLine(countSubArray(arr, n));
         
        int []arr1 = {2, 3, 5, 15, 7, 2};
        int n1 = arr1.Length;
        Console.WriteLine(countSubArray(arr1, n1));
    }
}
 
// This code is contributed by Sam007.


PHP
 1)
        {
            $div = $spf[$arr[$i]];
 
            // Fetch the last index of prime
            // divisor of element
            $last_ind = max($last_ind, $ind[$div]);
 
            // Update the current divisor index
            $ind[$div] = $i + 1;
            if($div != 0)
            $arr[$i] /= $div;
        }
 
        // Update result, we basically include
        // all required subarrays ending with
        // index arr[i].
        $count += $i - $last_ind + 1;
    }
    return $count;
}
 
// Driver code
sieve();
$arr = array(2, 3, 9);
$n = sizeof($arr);
echo countSubArray($arr, $n) . "\n";
 
$arr1 = array(2, 3, 5, 15, 7, 2);
$n1 = sizeof($arr1);
echo countSubArray($arr1, $n1);
 
// This code is contributed by ita_c
?>


Javascript


输出
3
12