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++
// 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
// 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
# 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#
// 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 |
Javascript
<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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!