给定长度为N且整数K的数组arr [] ,任务是对乘积为正整数的Kth幂的数组中的对进行计数,即
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)