📜  计算 Array 中乘积为任意正整数的 K 次方的对

📅  最后修改于: 2021-10-25 11:29:26             🧑  作者: Mango

给定一个长度为N的数组 arr[]和一个整数K ,任务是计算数组中乘积为正整数的 K次方的对,即

例子:

方法:这个问题的关键观察是以 Z K的形式表示任何数字,那么该数字的质因数分解的幂必须是 K 的倍数。 下面是步骤的说明:

  • 计算数组中每个数字的质因数分解并将质因数以键值对的形式存储在哈希映射中,其中键将是该元素的质因数,值将是该质数的幂因子模数 K,在该数字的质因数分解中。
    例如:
    Given Element be - 360 and K = 2
    Prime Factorization = 23 * 32 * 51
    
    Key-value pairs for this would be,
    => {(2, 3 % 2), (3, 2 % 2),
        (5, 1 % 2)}
    => {(2, 1), (5, 1)}
    
    // Notice that prime number 3 
    // is ignored because of the 
    // modulus value was 0
    
  • 遍历数组并创建一个频率哈希映射,其中键值对将被定义如下:
    Key: Prime Factors pairs mod K
    Value: Frequency of this Key
    
  • 最后,遍历数组的每个元素并检查哈希映射中是否存在所需的素因子。如果是,那么将有F个可能的对,其中 F 是频率。

    例子:

    Given Number be - 360, K = 3
    Prime Factorization -
    => {(3, 2), (5, 1)}
    
    Required Prime Factors -
    => {(p1, K - val1), ...(pn, K - valn)}
    => {(3, 3 - 2), (5, 3 - 1)}
    => {(3, 1), (5, 2)}  
    

下面是上述方法的实现:

C++
// C++ implementation to count the
// pairs whose product is Kth
// power of some integer Z
  
#include 
  
#define MAXN 100005
  
using namespace std;
  
// Smallest prime factor
int spf[MAXN];
  
// Sieve of eratosthenes
// for computing primes
void sieve()
{
    int i, j;
    spf[1] = 1;
    for (i = 2; i < MAXN; i++)
        spf[i] = i;
  
    // Loop for markig the factors
    // of prime number as non-prime
    for (i = 2; i < MAXN; i++) {
        if (spf[i] == i) {
            for (j = i * 2;
                 j < MAXN; j += i) {
                if (spf[j] == j)
                    spf[j] = i;
            }
        }
    }
}
  
// Function to factorize the
// number N into its prime factors
vector > getFact(int x)
{
    // Prime factors along with powers
    vector > factors;
  
    // Loop while the X is not
    // equal to 1
    while (x != 1) {
  
        // Smallest prime
        // factor of x
        int z = spf[x];
        int cnt = 0;
        // Count power of this
        // prime factor in x
        while (x % z == 0)
            cnt++, x /= z;
  
        factors.push_back(
            make_pair(z, cnt));
    }
    return factors;
}
  
// Function to count the pairs
int pairsWithKth(int a[], int n, int k)
{
  
    // Precomputation
    // for factorisation
    sieve();
  
    int answer = 0;
  
    // Data structure for storing
    // list L for each element along
    // with frequency of occurence
    map >,
        int>
        count_of_L;
  
    // Loop to iterate over the
    // elements of the array
    for (int i = 0; i < n; i++) {
  
        // Factorise each element
        vector >
            factors = getFact(a[i]);
        sort(factors.begin(),
             factors.end());
  
        vector > L;
  
        // Loop to iterate over the
        // factors of the element
        for (auto it : factors) {
            if (it.second % k == 0)
                continue;
            L.push_back(
                make_pair(
                    it.first,
                    it.second % k));
        }
  
        vector > Lx;
  
        // Loop to find the required prime
        // factors for each element of array
        for (auto it : L) {
  
            // Represents how much remainder
            // power needs to be added to
            // this primes power so as to make
            // it a multiple of k
            Lx.push_back(
                make_pair(
                    it.first,
                    (k - it.second + k) % k));
        }
  
        // Add occurences of
        // Lx till now to answer
        answer += count_of_L[Lx];
  
        // Increment the counter for L
        count_of_L[L]++;
    }
  
    return answer;
}
  
// Driver Code
int main()
{
    int n = 6;
    int a[n] = { 1, 3, 9, 8, 24, 1 };
    int k = 3;
  
    cout << pairsWithKth(a, n, k);
    return 0;
}


输出:
5

时间复杂度: O(N * log 2 N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。