Given three positive integers N, L and R. The task is to find the number of ways to form an array of size N where each element lies in the range [L, R] such that the total sum of all the elements of the array is divisible by 2.
Examples:
Input: N = 2, L = 1, R = 3
Output: 5
Explanation: Possible arrays having sum of all elements divisible by 2 are
[1, 1], [2, 2], [1, 3], [3, 1] and [3, 3]
Input: N = 3, L = 2, R = 2
Output: 1
Approach: The idea is to find the count of numbers having remainder 0 and 1 modulo 2 separately lying between L and R. This count can be calculated as follows:
We need to count numbers between range having remainder 1 modulo 2
F = First number in range of required type
L = Last number in range of required type
Count = (L – F) / 2
cnt0, and cnt1 represents Count of numbers between range of each type.
Then, using dynamic programming we can solve this problem. Let dp[i][j] denotes the number of ways where the sum of first i numbers modulo 2 is equal to j. Suppose we need to calculate dp[i][0], then it will have the following recurrence relation: dp[i][0] = (cnt0 * dp[i – 1][0] + cnt1 * dp[i – 1][1]). First term represents the number of ways upto (i – 1) having sum remainder as 0, so we can place cnt0 numbers in ith position such that sum remainder still remains 0. Second term represents the number of ways upto (i – 1) having sum remainder as 1, so we can place cnt1 numbers in ith position to such that sum remainder becomes 0. Similarly, we can calculate for dp[i][1].
Final answer will be denoted by dp[N][0].
Steps to solve the problem:
- Initialize tL to l and tR to r.
- Initialize arrays L and R with 0 for each type (modulo 0 and 1). Set L[l % 2] to l and R[r % 2] to r.
- Increment l and decrement r.
- If l is less than or equal to tR and r is greater than or equal to tL, set L[l % 2] to l and R[r % 2] to r.
- Initialize cnt0 and cnt1 as zero.
- If R[0] and L[0] are non-zero, set cnt0 to (R[0] – L[0]) / 2 + 1.
- If R[1] and L[1] are non-zero, set cnt1 to (R[1] – L[1]) / 2 + 1.
- Initialize a 2D array dp of size n x 2 with all elements set to 0.
- Set dp[1][0] to cnt0 and dp[1][1] to cnt1.
- For i from 2 to n:
- Set dp[i][0] to cnt0 times dp[i – 1][0] plus cnt1 times dp[i – 1][1].
- Set dp[i][1] to cnt0 times dp[i – 1][1] plus cnt1 times dp[i – 1][0].
- Return dp[n][0] as the required count of ways.
Below is the implementation of the above approach:
C++
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std; // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 int countWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int L[2] = { 0 }, R[2] = { 0 }; L[l % 2] = l, R[r % 2] = r; l++, r--; if (l <= tR && r >= tL) L[l % 2] = l, R[r % 2] = r; // Count of numbers of each type between range int cnt0 = 0, cnt1 = 0; if (R[0] && L[0]) cnt0 = (R[0] - L[0]) / 2 + 1; if (R[1] && L[1]) cnt1 = (R[1] - L[1]) / 2 + 1; int dp[n][2]; // Base Cases dp[1][0] = cnt0; dp[1][1] = cnt1; for ( int i = 2; i <= n; i++) { // Ways to form array whose sum upto // i numbers modulo 2 is 0 dp[i][0] = (cnt0 * dp[i - 1][0] + cnt1 * dp[i - 1][1]); // Ways to form array whose sum upto // i numbers modulo 2 is 1 dp[i][1] = (cnt0 * dp[i - 1][1] + cnt1 * dp[i - 1][0]); } // Return the required count of ways return dp[n][0]; } // Driver Code int main() { int n = 2, l = 1, r = 3; cout << countWays(n, l, r); return 0; } |
Java
// Java implementation of the approach class GFG { // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 static int countWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int [] L = new int [ 3 ]; int [] R = new int [ 3 ]; L[l % 2 ] = l; R[r % 2 ] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2 ] = l; R[r % 2 ] = r; } // Count of numbers of each type between range int cnt0 = 0 , cnt1 = 0 ; if (R[ 0 ] > 0 && L[ 0 ] > 0 ) cnt0 = (R[ 0 ] - L[ 0 ]) / 2 + 1 ; if (R[ 1 ] > 0 && L[ 1 ] > 0 ) cnt1 = (R[ 1 ] - L[ 1 ]) / 2 + 1 ; int [][] dp = new int [n + 1 ][ 3 ]; // Base Cases dp[ 1 ][ 0 ] = cnt0; dp[ 1 ][ 1 ] = cnt1; for ( int i = 2 ; i <= n; i++) { // Ways to form array whose sum upto // i numbers modulo 2 is 0 dp[i][ 0 ] = (cnt0 * dp[i - 1 ] [ 0 ] + cnt1 * dp[i - 1 ][ 1 ]); // Ways to form array whose sum upto // i numbers modulo 2 is 1 dp[i][ 1 ] = (cnt0 * dp[i - 1 ][ 1 ] + cnt1 * dp[i - 1 ][ 0 ]); } // Return the required count of ways return dp[n][ 0 ]; } // Driver Code public static void main(String[] args) { int n = 2 , l = 1 , r = 3 ; System.out.println(countWays(n, l, r)); } } // This code is contributed by Code_Mech. |
Python3
# Python3 implementation of the approach # Function to return the number of ways to # form an array of size n such that sum of # all elements is divisible by 2 def countWays(n, l, r): tL, tR = l, r # Represents first and last numbers # of each type (modulo 0 and 1) L = [ 0 for i in range ( 2 )] R = [ 0 for i in range ( 2 )] L[l % 2 ] = l R[r % 2 ] = r l + = 1 r - = 1 if (l < = tR and r > = tL): L[l % 2 ], R[r % 2 ] = l, r # Count of numbers of each type # between range cnt0, cnt1 = 0 , 0 if (R[ 0 ] and L[ 0 ]): cnt0 = (R[ 0 ] - L[ 0 ]) / / 2 + 1 if (R[ 1 ] and L[ 1 ]): cnt1 = (R[ 1 ] - L[ 1 ]) / / 2 + 1 dp = [[ 0 for i in range ( 2 )] for i in range (n + 1 )] # Base Cases dp[ 1 ][ 0 ] = cnt0 dp[ 1 ][ 1 ] = cnt1 for i in range ( 2 , n + 1 ): # Ways to form array whose sum # upto i numbers modulo 2 is 0 dp[i][ 0 ] = (cnt0 * dp[i - 1 ][ 0 ] + cnt1 * dp[i - 1 ][ 1 ]) # Ways to form array whose sum upto # i numbers modulo 2 is 1 dp[i][ 1 ] = (cnt0 * dp[i - 1 ][ 1 ] + cnt1 * dp[i - 1 ][ 0 ]) # Return the required count of ways return dp[n][ 0 ] # Driver Code n, l, r = 2 , 1 , 3 print (countWays(n, l, r)) # This code is contributed # by Mohit Kumar |
C#
// C# implementation of the approach using System; class GFG { // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 static int countWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int [] L = new int [3]; int [] R = new int [3]; L[l % 2] = l; R[r % 2] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2] = l; R[r % 2] = r; } // Count of numbers of each type between range int cnt0 = 0, cnt1 = 0; if (R[0] > 0 && L[0] > 0) cnt0 = (R[0] - L[0]) / 2 + 1; if (R[1] > 0 && L[1] > 0) cnt1 = (R[1] - L[1]) / 2 + 1; int [,] dp= new int [n + 1, 3]; // Base Cases dp[1, 0] = cnt0; dp[1, 1] = cnt1; for ( int i = 2; i <= n; i++) { // Ways to form array whose sum upto // i numbers modulo 2 is 0 dp[i, 0] = (cnt0 * dp[i - 1, 0] + cnt1 * dp[i - 1, 1]); // Ways to form array whose sum upto // i numbers modulo 2 is 1 dp[i, 1] = (cnt0 * dp[i - 1, 1] + cnt1 * dp[i - 1, 0]); } // Return the required count of ways return dp[n, 0]; } // Driver Code static void Main() { int n = 2, l = 1, r = 3; Console.WriteLine(countWays(n, l, r)); } } // This code is contributed by mits |
Javascript
<script> // JavaScript implementation of the approach // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 function countWays(n, l, r) { let tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) let L = new Array(3); let R = new Array(3); L[l % 2] = l; R[r % 2] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2] = l; R[r % 2] = r; } // Count of numbers of each type between range let cnt0 = 0, cnt1 = 0; if (R[0] > 0 && L[0] > 0) cnt0 = (R[0] - L[0]) / 2 + 1; if (R[1] > 0 && L[1] > 0) cnt1 = (R[1] - L[1]) / 2 + 1; let dp = new Array(n + 1); for (let i = 0; i <= n; i++) { dp[i] = new Array(3); for (let j = 0; j < 3; j++) { dp[i][j] = 0; } } // Base Cases dp[1][0] = cnt0; dp[1][1] = cnt1; for (let i = 2; i <= n; i++) { // Ways to form array whose sum upto // i numbers modulo 2 is 0 dp[i][0] = (cnt0 * dp[i - 1] [0] + cnt1 * dp[i - 1][1]); // Ways to form array whose sum upto // i numbers modulo 2 is 1 dp[i][1] = (cnt0 * dp[i - 1][1] + cnt1 * dp[i - 1][0]); } // Return the required count of ways return dp[n][0]; } let n = 2, l = 1, r = 3; document.write(countWays(n, l, r)); </script> |
PHP
<?php // PHP implementation of the approach // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 function countWays( $n , $l , $r ) { $tL = $l ; $tR = $r ; $L = array_fill (0, 2, 0); $R = array_fill (0, 2, 0); // Represents first and last numbers // of each type (modulo 0 and 1) $L [ $l % 2] = $l ; $R [ $r % 2] = $r ; $l ++; $r --; if ( $l <= $tR && $r >= $tL ) { $L [ $l % 2] = $l ; $R [ $r % 2] = $r ; } // Count of numbers of each type // between range $cnt0 = 0; $cnt1 = 0; if ( $R [0] && $L [0]) $cnt0 = ( $R [0] - $L [0]) / 2 + 1; if ( $R [1] && $L [1]) $cnt1 = ( $R [1] - $L [1]) / 2 + 1; $dp = array (); // Base Cases $dp [1][0] = $cnt0 ; $dp [1][1] = $cnt1 ; for ( $i = 2; $i <= $n ; $i ++) { // Ways to form array whose sum upto // i numbers modulo 2 is 0 $dp [ $i ][0] = ( $cnt0 * $dp [ $i - 1][0] + $cnt1 * $dp [ $i - 1][1]); // Ways to form array whose sum upto // i numbers modulo 2 is 1 $dp [ $i ][1] = ( $cnt0 * $dp [ $i - 1][1] + $cnt1 * $dp [ $i - 1][0]); } // Return the required count of ways return $dp [ $n ][0]; } // Driver Code $n = 2; $l = 1; $r = 3; echo countWays( $n , $l , $r ); // This code is contributed by Ryuga ?> |
5
Time Complexity: O(n)
Auxiliary Space: O(n)
Efficient approach : Space optimization O(1)
In previous approach we the current value dp[i] is only depend upon the previous 2 values i.e. dp[i-1][0] and dp[i-1][1]. So to optimize the space we can keep track of previous and current values by the help of three variables prevRow0, prevRow1 and currRow0 , currRow1 which will reduce the space complexity from O(N) to O(1).
Implementation Steps:
- Create 2 variables prevRow0 and prevRow1 to keep track of previous values of DP.
- Initialize base case prevRow0 = cnt0 , prevRow1 = cnt1. where cnt is Count of numbers of each type between range
- Create a variable currRow0 and currRow1 to store current value.
- Iterate over subproblem using loop and update curr.
- After every iteration update prevRow0 and prevRow1 for further iterations.
- At last return prevRow0.
Implementation:
C++
#include <bits/stdc++.h> using namespace std; // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 int countWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int L[2] = {0}, R[2] = {0}; L[l % 2] = l, R[r % 2] = r; l++, r--; if (l <= tR && r >= tL) L[l % 2] = l, R[r % 2] = r; // Count of numbers of each type between range int cnt0 = 0, cnt1 = 0; if (R[0] && L[0]) cnt0 = (R[0] - L[0]) / 2 + 1; if (R[1] && L[1]) cnt1 = (R[1] - L[1]) / 2 + 1; // Initialize variables for the first row int prevRow0 = cnt0, prevRow1 = cnt1; // Iterate through the rows and update the previous row values for ( int i = 2; i <= n; i++) { int currRow0 = (cnt0 * prevRow0) + (cnt1 * prevRow1); int currRow1 = (cnt0 * prevRow1) + (cnt1 * prevRow0); prevRow0 = currRow0; prevRow1 = currRow1; } // Return the required count of ways return prevRow0; } // Driver Code int main() { int n = 2, l = 1, r = 3; cout << countWays(n, l, r); return 0; } |
Java
import java.util.*; public class Main { // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 public static int countWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int [] L = new int [ 2 ]; int [] R = new int [ 2 ]; L[l % 2 ] = l; R[r % 2 ] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2 ] = l; R[r % 2 ] = r; } // Count of numbers of each type between range int cnt0 = 0 , cnt1 = 0 ; if (R[ 0 ] != 0 && L[ 0 ] != 0 ) { cnt0 = (R[ 0 ] - L[ 0 ]) / 2 + 1 ; } if (R[ 1 ] != 0 && L[ 1 ] != 0 ) { cnt1 = (R[ 1 ] - L[ 1 ]) / 2 + 1 ; } // Initialize variables for the first row int prevRow0 = cnt0, prevRow1 = cnt1; // Iterate through the rows and update the previous // row values for ( int i = 2 ; i <= n; i++) { int currRow0 = (cnt0 * prevRow0) + (cnt1 * prevRow1); int currRow1 = (cnt0 * prevRow1) + (cnt1 * prevRow0); prevRow0 = currRow0; prevRow1 = currRow1; } // Return the required count of ways return prevRow0; } // Driver Code public static void main(String[] args) { int n = 2 , l = 1 , r = 3 ; System.out.println(countWays(n, l, r)); } } |
Python
# Function to return the number of ways to # form an array of size n such that sum of # all elements is divisible by 2 def countWays(n, l, r): tL, tR = l, r # Represents first and last numbers # of each type (modulo 0 and 1) L, R = [ 0 , 0 ], [ 0 , 0 ] L[l % 2 ] = l R[r % 2 ] = r l + = 1 r - = 1 if l < = tR and r > = tL: L[l % 2 ] = l R[r % 2 ] = r # Count of numbers of each type between range cnt0, cnt1 = 0 , 0 if R[ 0 ] and L[ 0 ]: cnt0 = (R[ 0 ] - L[ 0 ]) / / 2 + 1 if R[ 1 ] and L[ 1 ]: cnt1 = (R[ 1 ] - L[ 1 ]) / / 2 + 1 # Initialize variables for the first row prevRow0, prevRow1 = cnt0, cnt1 # Iterate through the rows and update the previous row values for i in range ( 2 , n + 1 ): currRow0 = (cnt0 * prevRow0) + (cnt1 * prevRow1) currRow1 = (cnt0 * prevRow1) + (cnt1 * prevRow0) prevRow0 = currRow0 prevRow1 = currRow1 # Return the required count of ways return prevRow0 # Driver Code if __name__ = = '__main__' : n, l, r = 2 , 1 , 3 print (countWays(n, l, r)) |
C#
using System; class GFG { // Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 static int CountWays( int n, int l, int r) { int tL = l, tR = r; // Represents first and last numbers // of each type (modulo 0 and 1) int [] L = { 0, 0 }; int [] R = { 0, 0 }; L[l % 2] = l; R[r % 2] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2] = l; R[r % 2] = r; } // Count of numbers of each type between range int cnt0 = 0, cnt1 = 0; if (R[0] != 0 && L[0] != 0) cnt0 = (R[0] - L[0]) / 2 + 1; if (R[1] != 0 && L[1] != 0) cnt1 = (R[1] - L[1]) / 2 + 1; // Initialize variables for the first row int prevRow0 = cnt0, prevRow1 = cnt1; // Iterate through the rows and update the previous row values for ( int i = 2; i <= n; i++) { int currRow0 = (cnt0 * prevRow0) + (cnt1 * prevRow1); int currRow1 = (cnt0 * prevRow1) + (cnt1 * prevRow0); prevRow0 = currRow0; prevRow1 = currRow1; } // Return the required count of ways return prevRow0; } // Driver Code static void Main( string [] args) { int n = 2, l = 1, r = 3; Console.WriteLine(CountWays(n, l, r)); // Wait for key press to exit Console.ReadLine(); } } |
Javascript
// Function to return the number of ways to // form an array of size n such that sum of // all elements is divisible by 2 function countWays(n, l, r) { let tL = l; let tR = r; // Represents first and last numbers of each type (modulo 0 and 1) let L = [0, 0]; let R = [0, 0]; L[l % 2] = l; R[r % 2] = r; l++; r--; if (l <= tR && r >= tL) { L[l % 2] = l; R[r % 2] = r; } // Count of numbers of each type between range let cnt0 = 0; let cnt1 = 0; if (R[0] !== 0 && L[0] !== 0) cnt0 = Math.floor((R[0] - L[0]) / 2) + 1; if (R[1] !== 0 && L[1] !== 0) cnt1 = Math.floor((R[1] - L[1]) / 2) + 1; // Initialize variables for the first row let prevRow0 = cnt0; let prevRow1 = cnt1; // Iterate through the rows and update the previous row values for (let i = 2; i <= n; i++) { let currRow0 = cnt0 * prevRow0 + cnt1 * prevRow1; let currRow1 = cnt0 * prevRow1 + cnt1 * prevRow0; prevRow0 = currRow0; prevRow1 = currRow1; } // Return the required count of ways return prevRow0; } // Driver Code const n = 2; const l = 1; const r = 3; console.log(countWays(n, l, r)); |
Output:
5
Time Complexity: O(n)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!