给定一个长度为N的数组 arr[]和一个整数K ,任务是计算数组中乘积为正整数的 K次方的对,即
A[i] * A[j] = ZK for any positive integer Z.
例子:
Input: arr[] = {1, 3, 9, 8, 24, 1}, K = 3
Output: 5
Explanation:
There are 5 such pairs, those can be represented as Z3 –
A[0] * A[3] = 1 * 8 = 2^3
A[0] * A[5] = 1 * 1 = 1^3
A[1] * A[2] = 3 * 9 = 3^3
A[2] * A[4] = 9 * 24 = 6^3
A[3] * A[5] = 8 * 1 = 2^3
Input: arr[] = {7, 4, 10, 9, 2, 8, 8, 7, 3, 7}, K = 2
Output: 7
Explanation:
There are 7 such pairs, those can be represented as Z2
方法:这个问题的关键观察是以 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 现场工作专业课程和学生竞争性编程现场课程。