Given a K and a matrix Q[][] consisting of queries of the form {N, M}, the task for each query is to count the number of strings possible of all lengths from Q[i][0] to Q[i][1] satisfying the following properties:
- The frequency of 0‘s is equal to a multiple of K.
- Two strings are said to be different only if the frequencies of 0‘s and 1‘s are different
Since the answer can be quite large, compute the answer by mod 109 + 7.
Examples:
Input: K = 3, Q[][] = {{1, 3}}
Output: 4
Explanation:
All possible strings of length 1 : {“1”}
All possible strings of length 2 : {“11”}
All possible strings of length 3 : {“111”, “000”}
Therefore, a total of 4 strings can be generated.Input: K = 3, Q[][] = {{1, 4}, {3, 7}}
Output:
7
24
Naive Approach:
Follow the steps below to solve the problem:
- Initialize an array dp[] such that dp[i] denotes the number of strings possible of length i.
- Initialize dp[0] = 1.
- For every ith Length, at most two possibilities arise:
- Appending ‘1’ to the strings of length i – 1.
- Add K 0‘s to all possible strings of length i-K.
- Finally, for each query Q[i], print the sum of all dp[j] for Q[i][0] <= j <= Q[i][1].
Time Complexity: O(N*Q)
Auxiliary Space: O(N)
Efficient Approach:
The above approach can be optimized using Prefix Sum Array. Follow the steps below:
- Update the dp[] array by following the steps in the above approach.
- Compute prefix sum array of the dp[] array.
- Finally, for each query Q[i], calculate dp[Q[i][1]] – dp[Q[i][0] – 1] and print as result.
Below is the implementation of the above approach:
// C++ Program to implement // the above approach #include <bits/stdc++.h> using namespace std;
const int N = 1e5 + 5;
const int MOD = 1000000007;
long int dp[N];
// Function to calculate the // count of possible strings void countStrings( int K,
vector<vector< int > > Q)
{ // Initialize dp[0]
dp[0] = 1;
// dp[i] represents count of
// strings of length i
for ( int i = 1; i < N; i++) {
dp[i] = dp[i - 1];
// Add dp[i-k] if i>=k
if (i >= K)
dp[i]
= (dp[i] + dp[i - K]) % MOD;
}
// Update Prefix Sum Array
for ( int i = 1; i < N; i++) {
dp[i] = (dp[i] + dp[i - 1]) % MOD;
}
for ( int i = 0; i < Q.size(); i++) {
long int ans
= dp[Q[i][1]] - dp[Q[i][0] - 1];
if (ans < 0)
ans = ans + MOD;
cout << ans << endl;
}
} // Driver Code int main()
{ int K = 3;
vector<vector< int > > Q
= { { 1, 4 }, { 3, 7 } };
countStrings(K, Q);
return 0;
} |
// Java program to implement // the above approach import java.util.*;
class GFG{
static int N = ( int )(1e5 + 5 );
static int MOD = 1000000007 ;
static int []dp = new int [N];
// Function to calculate the // count of possible Strings static void countStrings( int K, int [][] Q)
{ // Initialize dp[0]
dp[ 0 ] = 1 ;
// dp[i] represents count of
// Strings of length i
for ( int i = 1 ; i < N; i++)
{
dp[i] = dp[i - 1 ];
// Add dp[i-k] if i>=k
if (i >= K)
dp[i] = (dp[i] + dp[i - K]) % MOD;
}
// Update Prefix Sum Array
for ( int i = 1 ; i < N; i++)
{
dp[i] = (dp[i] + dp[i - 1 ]) % MOD;
}
for ( int i = 0 ; i < Q.length; i++)
{
int ans = dp[Q[i][ 1 ]] - dp[Q[i][ 0 ] - 1 ];
if (ans < 0 )
ans = ans + MOD;
System.out.print(ans + "\n" );
}
} // Driver Code public static void main(String[] args)
{ int K = 3 ;
int [][]Q = { { 1 , 4 }, { 3 , 7 } };
countStrings(K, Q);
} } // This code is contributed by 29AjayKumar |
# Python3 program to implement # the above approach N = int ( 1e5 + 5 )
MOD = 1000000007
dp = [ 0 ] * N
# Function to calculate the # count of possible strings def countStrings(K, Q):
# Initialize dp[0]
dp[ 0 ] = 1
# dp[i] represents count of
# strings of length i
for i in range ( 1 , N):
dp[i] = dp[i - 1 ]
# Add dp[i-k] if i>=k
if (i > = K):
dp[i] = (dp[i] + dp[i - K]) % MOD
# Update Prefix Sum Array
for i in range ( 1 , N):
dp[i] = (dp[i] + dp[i - 1 ]) % MOD
for i in range ( len (Q)):
ans = dp[Q[i][ 1 ]] - dp[Q[i][ 0 ] - 1 ]
if (ans < 0 ):
ans + = MOD
print (ans)
# Driver Code K = 3
Q = [ [ 1 , 4 ], [ 3 , 7 ] ]
countStrings(K, Q) # This code is contributed by Shivam Singh |
// C# program to implement // the above approach using System;
class GFG{
static int N = ( int )(1e5 + 5);
static int MOD = 1000000007;
static int []dp = new int [N];
// Function to calculate the // count of possible Strings static void countStrings( int K,
int [,] Q)
{ // Initialize dp[0]
dp[0] = 1;
// dp[i] represents count of
// Strings of length i
for ( int i = 1; i < N; i++)
{
dp[i] = dp[i - 1];
// Add dp[i-k] if i>=k
if (i >= K)
dp[i] = (dp[i] +
dp[i - K]) % MOD;
}
// Update Prefix Sum Array
for ( int i = 1; i < N; i++)
{
dp[i] = (dp[i] +
dp[i - 1]) % MOD;
}
for ( int i = 0; i < Q.GetLength(0); i++)
{
int ans = dp[Q[i, 1]] -
dp[Q[i, 0] - 1];
if (ans < 0)
ans = ans + MOD;
Console.Write(ans + "\n" );
}
} // Driver Code public static void Main(String[] args)
{ int K = 3;
int [,]Q = {{1, 4}, {3, 7}};
countStrings(K, Q);
} } // This code is contributed by 29AjayKumar |
<script> // Javascript program to implement // the above approach let N = parseInt((1e5 + 5)); let MOD = 1000000007; let dp = Array(N).fill(0); // Function to calculate the // count of possible Strings function countStrings(K, Q)
{ // Initialize dp[0]
dp[0] = 1;
// dp[i] represents count of
// Strings of length i
for (let i = 1; i < N; i++)
{
dp[i] = dp[i - 1];
// Add dp[i-k] if i>=k
if (i >= K)
dp[i] = (dp[i] + dp[i - K]) % MOD;
}
// Update Prefix Sum Array
for (let i = 1; i < N; i++)
{
dp[i] = (dp[i] + dp[i - 1]) % MOD;
}
for (let i = 0; i < Q.length; i++)
{
var ans = dp[Q[i][1]] - dp[Q[i][0] - 1];
if (ans < 0)
ans = ans + MOD;
document.write(ans + "\n" );
}
} // Driver Code var K = 3;
let Q = [ [ 1, 4 ], [ 3, 7 ] ]; countStrings(K, Q); // This code is contributed by gauravrajput1 </script> |
7 24
Time Complexity: O(N + Q)
Auxiliary Space: O(N)