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++ 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 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 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# 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 |
<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 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:
#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;
} |
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));
}
} |
# 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))
|
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();
}
} |
// 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)