Given an array arr of length N and an integer K, the task is to count the number of possible subsequences of length at most K which contains distinct prime elements from the array.
Examples:
Input: arr[] = {1, 2, 2, 3, 3, 4, 5}, N = 7, K = 3
Output: 18
Explanation: {}, {2}, {2}, {3}, {3}, {5}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 5}, {2, 5}, {3, 5}, {3, 5}, {2, 3, 5}, {2, 3, 5}, {2, 3, 5} and {2, 3, 5} are the subsequences.
Input arr[] = {2, 4, 6, 7, 3, 9, 11, 5}, N = 8, K = 3
Output: 26
Approach:
Using Sieve of Eratosthenes, precompute and store all prime numbers. Calculate and store the frequency of every prime number in the given array. Using a dynamic programming approach, calculate the number of subsequences of length 2 to K. Keep updating ans by adding the possible distinct combinations of length 2 to K for each dp[i]. Once calculated, add the frequency of all the primes + 1 as the subsequences of length 1 and 0. The final value of ans gives the desired result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool prime[100001];
void SieveOfEratosthenes()
{
memset (prime, true , sizeof (prime));
prime[0] = prime[1] = false ;
for ( int p = 2; p * p <= 100000; p++) {
if (prime[p] == true ) {
for ( int i = p * p;
i <= 100000;
i += p)
prime[i] = false ;
}
}
}
int distinctPrimeSubSeq(
int a[],
int n, int k)
{
SieveOfEratosthenes();
vector< int > primes;
for ( int i = 0; i < n; i++) {
if (prime[a[i]])
primes.push_back(a[i]);
}
int l = primes.size();
sort(primes.begin(),
primes.end());
vector< int > b;
vector< int > dp;
int sum = 0;
for ( int i = 0; i < l;) {
int count = 1, x = a[i];
i++;
while (i < l && a[i] == x) {
count++;
i++;
}
b.push_back(count);
dp.push_back(count);
sum += count;
}
int of_length = 2;
int len = dp.size();
int ans = 0;
while (of_length <= k) {
int freq = 0;
int prev = 0;
for ( int i = 0; i < (len - 1); i++) {
freq += dp[i];
int j = sum - freq;
int subseq = b[i] * j;
ans += subseq;
dp[i] = subseq;
prev += dp[i];
}
len--;
sum = prev;
of_length++;
}
ans += (l + 1);
return ans;
}
int main()
{
int a[] = { 1, 2, 2, 3, 3, 4, 5 };
int n = sizeof (a) / sizeof ( int );
int k = 3;
cout << distinctPrimeSubSeq(a, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean []prime =
new boolean [ 100001 ];
static void SieveOfEratosthenes()
{
for ( int i = 0 ; i < prime.length; i++)
prime[i] = true ;
prime[ 0 ] = prime[ 1 ] = false ;
for ( int p = 2 ; p * p < 100000 ; p++)
{
if (prime[p] == true )
{
for ( int i = p * p;
i <= 100000 ; i += p)
prime[i] = false ;
}
}
}
static int distinctPrimeSubSeq( int a[],
int n,
int k)
{
SieveOfEratosthenes();
Vector<Integer> primes =
new Vector<>();
for ( int i = 0 ; i < n; i++)
{
if (prime[a[i]])
primes.add(a[i]);
}
int l = primes.size();
Collections.sort(primes);
Vector<Integer> b =
new Vector<>();
Vector<Integer> dp =
new Vector<>();
int sum = 0 ;
for ( int i = 0 ; i < l;)
{
int count = 1 , x = a[i];
i++;
while (i < l && a[i] == x)
{
count++;
i++;
}
b.add(count);
dp.add(count);
sum += count;
}
int of_length = 2 ;
int len = dp.size();
int ans = 0 ;
while (of_length < k)
{
int freq = 0 ;
int prev = 0 ;
for ( int i = 0 ;
i < (len - 1 ); i++)
{
freq += dp.elementAt(i);
int j = sum - freq;
int subseq = b.elementAt(i) * j;
ans += subseq;
dp.add(i, subseq);
prev += dp.elementAt(i);
}
len--;
sum = prev;
of_length++;
}
ans += (l + 3 );
return ans;
}
public static void main(String[] args)
{
int a[] = { 1 , 2 , 2 , 3 , 3 , 4 , 5 };
int n = a.length;
int k = 3 ;
System.out.print(distinctPrimeSubSeq(a, n, k));
}
}
|
Python3
prime = [ True ] * 1000000
def SieveOfEratosthenes():
global prime
prime[ 0 ] = prime[ 1 ] = False
p = 2
while p * p < = 100000 :
if (prime[p] = = True ):
for i in range (p * p,
100001 , p):
prime[i] = False
p + = 1
def distinctPrimeSubSeq(a,
n, k):
SieveOfEratosthenes()
primes = []
for i in range (n):
if (prime[a[i]]):
primes.append(a[i])
l = len (primes)
primes.sort()
b = []
dp = []
sum = 0
i = 0
while i < l:
count = 1
x = a[i]
i + = 1
while (i < l and
a[i] = = x):
count + = 1
i + = 1
b.append(count)
dp.append(count)
sum + = count
of_length = 2
leng = len (dp)
ans = 0
while (of_length < = k):
freq = 0
prev = 0
for i in range (leng - 1 ):
freq + = dp[i]
j = sum - freq
subseq = b[i] * j
ans + = subseq
dp[i] = subseq
prev + = dp[i]
leng - = 1
sum = prev
of_length + = 1
ans + = (l + 1 )
return ans
if __name__ = = "__main__" :
a = [ 1 , 2 , 2 ,
3 , 3 , 4 , 5 ]
n = len (a)
k = 3
print (distinctPrimeSubSeq(a, n, k))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool []prime =
new bool [100001];
static void SieveOfEratosthenes()
{
for ( int i = 0; i < prime.Length; i++)
prime[i] = true ;
prime[0] = prime[1] = false ;
for ( int p = 2; p * p < 100000; p++)
{
if (prime[p] == true )
{
for ( int i = p * p;
i <= 100000; i += p)
prime[i] = false ;
}
}
}
static int distinctPrimeSubSeq( int []a,
int n,
int k)
{
SieveOfEratosthenes();
List< int > primes = new List< int >();
for ( int i = 0; i < n; i++)
{
if (prime[a[i]])
primes.Add(a[i]);
}
int l = primes.Count;
primes.Sort();
List< int > b = new List< int >();
List< int > dp = new List< int >();
int sum = 0;
for ( int i = 0; i < l;)
{
int count = 1, x = a[i];
i++;
while (i < l && a[i] == x)
{
count++;
i++;
}
b.Add(count);
dp.Add(count);
sum += count;
}
int of_length = 2;
int len = dp.Count;
int ans = 0;
while (of_length <= k)
{
int freq = 0;
int prev = 0;
for ( int i = 0;
i < (len ); i++)
{
freq += dp[i];
int j = sum - freq;
int subseq = b[i] * j;
ans += subseq;
dp[i] = subseq;
prev += dp[i];
}
len--;
sum = prev;
of_length++;
}
ans += (l + 1);
return ans;
}
public static void Main(String[] args)
{
int []a = {1, 2, 2, 3, 3, 4, 5};
int n = a.Length;
int k = 3;
Console.Write(distinctPrimeSubSeq(a, n, k));
}
}
|
Javascript
<script>
let prime = new Array(100001);
function SieveOfEratosthenes()
{
prime.fill( true )
prime[0] = prime[1] = false ;
for (let p = 2; p * p <= 100000; p++) {
if (prime[p] == true ) {
for (let i = p * p;
i <= 100000;
i += p)
prime[i] = false ;
}
}
}
function distinctPrimeSubSeq(a, n, k)
{
SieveOfEratosthenes();
let primes = new Array();
for (let i = 0; i < n; i++) {
if (prime[a[i]])
primes.push(a[i]);
}
let l = primes.length;
primes.sort((a, b) => a - b)
let b = new Array();
let dp = new Array();
let sum = 0;
for (let i = 0; i < l;) {
let count = 1, x = a[i];
i++;
while (i < l && a[i] == x) {
count++;
i++;
}
b.push(count);
dp.push(count);
sum += count;
}
let of_length = 2;
let len = dp.length;
let ans = 0;
while (of_length <= k) {
let freq = 0;
let prev = 0;
for (let i = 0; i < (len - 1); i++) {
freq += dp[i];
let j = sum - freq;
let subseq = b[i] * j;
ans += subseq;
dp[i] = subseq;
prev += dp[i];
}
len--;
sum = prev;
of_length++;
}
ans += (l + 1);
return ans;
}
let a = [ 1, 2, 2, 3, 3, 4, 5 ];
let n = a.length;
let k = 3;
document.write(distinctPrimeSubSeq(a, n, k));
</script>
|
Time Complexity: O(K*(Distinct number of prime))
Space Complexity: O(N)