Count of sub-sets of size n with total element sum divisible by 3

Last Updated : 21 Sep, 2023

Given an integer n and a range [l, r], the task is to find the count of total sub-sets of size n with integers from the given range such that the total sum of its elements is divisible by 3.
Examples:

Input: n = 2, l = 1, r = 5
Output:
Possible sub-sets are {1, 2}, {2, 1}, {3, 3}, {5, 1}, {1, 5}, {4, 2}, {2, 4}, {5, 4} and {4, 5}
Input: n = 3, l = 9, r = 9
Output:
{9, 9, 9} is the only possible sub-set

Approach: Since we need the sum of the sub-set elements to be divisible by 3. So, instead of caring about the numbers, we will count the numbers such that they give remainder 0, 1 and 2 on dividing with 3 separately by the formula given below:

For example, an element k such that k % 3 = 2 can be found as k = 3 * x + 2 for some integer x
Then we have l ? (3 * x) + 2 ? r
l – 2 ? (3 * x) ? r – 2
ceil((l – 2) / 3) ? x ? floor((r – 2) / 3)

Now, by dynamic programming dp[i][j] we can check how many elements will give a sum that is divisible by 3. Here dp[i][j] represents the sum of first i elements that give remainder j on dividing by 3.
Below is the implementation of the above approach:

C++

 `// C++ implementation of the approach` `#include ` `#define MOD 1000000007` `#define ll long long int` `using` `namespace` `std;`   `// Function to return the total number of ` `// required sub-sets` `int` `totalSubSets(ll n, ll l, ll r)` `{`   `    ``// Variable to store total elements ` `    ``// which on dividing by 3  give ` `    ``// remainder 0, 1 and 2 respectively` `    ``ll zero = ``floor``((``double``)r / 3)` `              ``- ``ceil``((``double``)l / 3) + 1;` `    ``ll one = ``floor``((``double``)(r - 1) / 3)` `             ``- ``ceil``((``double``)(l - 1) / 3) + 1;` `    ``ll two = ``floor``((``double``)(r - 2) / 3)` `             ``- ``ceil``((``double``)(l - 2) / 3) + 1;`   `    ``// Create a dp table` `    ``ll dp[n][3];` `    ``memset``(dp, 0, ``sizeof``(dp));` `    ``dp[0][0] = zero;` `    ``dp[0][1] = one;` `    ``dp[0][2] = two;`   `    ``// Process for n states and store` `    ``// the sum (mod 3) for 0, 1 and 2` `    ``for` `(ll i = 1; i < n; ++i) {`   `        ``// Use of MOD for large numbers` `        ``dp[i][0] = ((dp[i - 1][0] * zero)` `                    ``+ (dp[i - 1][1] * two)` `                    ``+ (dp[i - 1][2] * one))` `                   ``% MOD;` `        ``dp[i][1] = ((dp[i - 1][0] * one)` `                    ``+ (dp[i - 1][1] * zero)` `                    ``+ (dp[i - 1][2] * two))` `                   ``% MOD;` `        ``dp[i][2] = ((dp[i - 1][0] * two)` `                    ``+ (dp[i - 1][1] * one)` `                    ``+ (dp[i - 1][2] * zero))` `                   ``% MOD;` `    ``}`   `    ``// Final answer store at dp[n - 1][0]` `    ``return` `dp[n - 1][0];` `}`   `// Driver Program` `int` `main()` `{` `    ``ll n = 5;` `    ``ll l = 10;` `    ``ll r = 100;` `    ``cout << totalSubSets(n, l, r);` `    ``return` `0;` `}`

Java

 `// Java implementation of the approach`   `class` `GFG` `{` `        `  `    ``static` `int` `MOD = ``1000000007``;` `    `  `    ``// Function to return the total number of ` `    ``// required sub-sets` `    ``static` `int` `totalSubSets(``int` `n, ``int` `l, ``int` `r)` `    ``{` `    `  `        ``// Variable to store total elements ` `        ``// which on dividing by 3 give ` `        ``// remainder 0, 1 and 2 respectively` `        ``int` `zero = (``int``)Math.floor((``double``)r / ``3``)` `                ``- (``int``)Math.ceil((``double``)l / ``3``) + ``1``;` `        ``int` `one = (``int``)Math.floor((``double``)(r - ``1``) / ``3``)` `                ``- (``int``)Math.ceil((``double``)(l - ``1``) / ``3``) + ``1``;` `        ``int` `two = (``int``)Math.floor((``double``)(r - ``2``) / ``3``)` `                ``- (``int``)Math.ceil((``double``)(l - ``2``) / ``3``) + ``1``;` `    `  `        ``// Create a dp table` `        ``int` `[][] dp = ``new` `int``[n][``3``];` `    `  `        ``dp[``0``][``0``] = zero;` `        ``dp[``0``][``1``] = one;` `        ``dp[``0``][``2``] = two;` `    `  `        ``// Process for n states and store` `        ``// the sum (mod 3) for 0, 1 and 2` `        ``for` `(``int` `i = ``1``; i < n; ++i)` `        ``{` `    `  `            ``// Use of MOD for large numbers` `            ``dp[i][``0``] = ((dp[i - ``1``][``0``] * zero)` `                        ``+ (dp[i - ``1``][``1``] * two)` `                        ``+ (dp[i - ``1``][``2``] * one))` `                    ``% MOD;` `            ``dp[i][``1``] = ((dp[i - ``1``][``0``] * one)` `                        ``+ (dp[i - ``1``][``1``] * zero)` `                        ``+ (dp[i - ``1``][``2``] * two))` `                    ``% MOD;` `            ``dp[i][``2``] = ((dp[i - ``1``][``0``] * two)` `                        ``+ (dp[i - ``1``][``1``] * one)` `                        ``+ (dp[i - ``1``][``2``] * zero))` `                    ``% MOD;` `        ``}` `    `  `        ``// Final answer store at dp[n - 1][0]` `        ``return` `dp[n - ``1``][``0``];` `    ``}` `    `  `    ``// Driver Program` `    ``public` `static` `void` `main(String []args)` `    ``{` `        ``int` `n = ``5``;` `        ``int` `l = ``10``;` `        ``int` `r = ``100``;` `        ``System.out.println(totalSubSets(n, l, r));` `    ``}` `}`   `// This code is contributed by ihritik`

Python3

 `# Python3 implementation of the approach ` `import` `math`   `# Function to return the total` `# number of required sub-sets ` `def` `totalSubSets(n, l, r):` `    `  `    ``MOD ``=` `1000000007` `;` `    `  `    ``# Variable to store total elements ` `    ``# which on dividing by 3 give ` `    ``# remainder 0, 1 and 2 respectively ` `    ``zero ``=` `(math.floor(r ``/` `3``) ``-` `            ``math.ceil(l ``/` `3``) ``+` `1``); ` `    ``one ``=` `(math.floor((r ``-` `1``) ``/` `3``) ``-` `           ``math.ceil((l ``-` `1``) ``/` `3``) ``+` `1``); ` `    ``two ``=` `(math.floor((r ``-` `2``) ``/` `3``) ``-` `           ``math.ceil((l ``-` `2``) ``/` `3``) ``+` `1``); `   `    ``# Create a dp table ` `    ``dp ``=` `[[``0` `for` `x ``in` `range``(``3``)] ` `             ``for` `y ``in` `range``(n)] ` `            `  `    ``dp[``0``][``0``] ``=` `zero; ` `    ``dp[``0``][``1``] ``=` `one; ` `    ``dp[``0``][``2``] ``=` `two; `   `    ``# Process for n states and store ` `    ``# the sum (mod 3) for 0, 1 and 2 ` `    ``for` `i ``in` `range``(``1``, n):`   `        ``# Use of MOD for large numbers ` `        ``dp[i][``0``] ``=` `((dp[i ``-` `1``][``0``] ``*` `zero) ``+` `                    ``(dp[i ``-` `1``][``1``] ``*` `two) ``+` `                    ``(dp[i ``-` `1``][``2``] ``*` `one)) ``%` `MOD; ` `        ``dp[i][``1``] ``=` `((dp[i ``-` `1``][``0``] ``*` `one) ``+` `                    ``(dp[i ``-` `1``][``1``] ``*` `zero) ``+` `                    ``(dp[i ``-` `1``][``2``] ``*` `two)) ``%` `MOD; ` `        ``dp[i][``2``] ``=` `((dp[i ``-` `1``][``0``] ``*` `two)``+` `                    ``(dp[i ``-` `1``][``1``] ``*` `one) ``+` `                    ``(dp[i ``-` `1``][``2``] ``*` `zero)) ``%` `MOD; `   `    ``# Final answer store at dp[n - 1][0] ` `    ``return` `dp[n ``-` `1``][``0``];`   `# Driver Code` `n ``=` `5``; ` `l ``=` `10``; ` `r ``=` `100``; ` `print``(totalSubSets(n, l, r)); ` `    `  `# This code is contributed` `# by chandan_jnu`

C#

 `// C# implementation of the approach` `using` `System;`   `class` `GFG` `{` `        `  `    ``static` `int` `MOD = 1000000007;` `    `  `    ``// Function to return the total number of ` `    ``// required sub-sets` `    ``static` `int` `totalSubSets(``int` `n, ``int` `l, ``int` `r)` `    ``{` `    `  `        ``// Variable to store total elements ` `        ``// which on dividing by 3 give ` `        ``// remainder 0, 1 and 2 respectively` `        ``int` `zero = (``int``)Math.Floor((``double``)r / 3)` `                ``- (``int``)Math.Ceiling((``double``)l / 3) + 1;` `        ``int` `one = (``int``)Math.Floor((``double``)(r - 1) / 3)` `                ``- (``int``)Math.Ceiling((``double``)(l - 1) / 3) + 1;` `        ``int` `two = (``int``)Math.Floor((``double``)(r - 2) / 3)` `                ``- (``int``)Math.Ceiling((``double``)(l - 2) / 3) + 1;` `    `  `        ``// Create a dp table` `        ``int` `[, ] dp = ``new` `int``[n, 3];` `    `  `        ``dp[0,0] = zero;` `        ``dp[0,1] = one;` `        ``dp[0,2] = two;` `    `  `        ``// Process for n states and store` `        ``// the sum (mod 3) for 0, 1 and 2` `        ``for` `(``int` `i = 1; i < n; ++i) ` `        ``{` `    `  `            ``// Use of MOD for large numbers` `            ``dp[i,0] = ((dp[i - 1, 0] * zero)` `                        ``+ (dp[i - 1, 1] * two)` `                        ``+ (dp[i - 1, 2] * one))` `                    ``% MOD;` `            ``dp[i,1] = ((dp[i - 1, 0] * one)` `                        ``+ (dp[i - 1, 1] * zero)` `                        ``+ (dp[i - 1, 2] * two))` `                    ``% MOD;` `            ``dp[i,2] = ((dp[i - 1, 0] * two)` `                        ``+ (dp[i - 1, 1] * one)` `                        ``+ (dp[i - 1, 2] * zero))` `                    ``% MOD;` `        ``}` `    `  `        ``// Final answer store at dp[n - 1,0]` `        ``return` `dp[n - 1, 0];` `    ``}` `    `  `    ``// Driver Program` `    ``public` `static` `void` `Main()` `    ``{` `        ``int` `n = 5;` `        ``int` `l = 10;` `        ``int` `r = 100;` `        ``Console.WriteLine(totalSubSets(n, l, r));` `    ``}` `}`   `// This code is contributed by ihritik`

Javascript

 ``

PHP

 ``

Output

```80107136

```

Time Complexity: O(n)

Auxiliary Space: O(n), since n extra space has been taken.

Efficient approach : Space optimization O(1)

To optimize the space complexity of the previous code, we can observe that we only need to keep track of the sum (mod 3) of the previous state, i.e., dp[i-1][0], dp[i-1][1], and dp[i-1][2], to compute the sum (mod 3) of the current state dp[i][0], dp[i][1], and dp[i][2]. Hence, we can replace the 2D dp array with three variables sum0, sum1, and sum2 to keep track of the sum (mod 3) of the previous state.

Implementation Steps:

• Create variable zero ,one and two to store total elements which on dividing by 3 give remainder 0, 1 and 2 respectively .
• Now Initialize the sum (mod 3) of the previous state sum0, sum1 and sum2.
• Now iterate over subproblems and update current values.
• After every iteration update sum0, sum1 and sum2 for further iterations.
• At last return final answer stored in sum0.

Implementation:

C++

 `// C++ implementation of the approach` `#include ` `#define MOD 1000000007` `#define ll long long int` `using` `namespace` `std;`   `// Function to return the total number of` `// required sub-sets` `int` `totalSubSets(ll n, ll l, ll r)` `{`   `    ``// Variable to store total elements` `    ``// which on dividing by 3 give` `    ``// remainder 0, 1 and 2 respectively` `    ``ll zero = ``floor``((``double``)r / 3)` `            ``- ``ceil``((``double``)l / 3) + 1;` `    ``ll one = ``floor``((``double``)(r - 1) / 3)` `            ``- ``ceil``((``double``)(l - 1) / 3) + 1;` `    ``ll two = ``floor``((``double``)(r - 2) / 3)` `            ``- ``ceil``((``double``)(l - 2) / 3) + 1;`   `    ``// Initialize the sum (mod 3) of the previous state` `    ``ll sum0 = zero, sum1 = one, sum2 = two;`   `    ``// Process for n states and store` `    ``// the sum (mod 3) for 0, 1 and 2` `    ``for` `(ll i = 1; i < n; ++i) {`   `        ``// Compute the sum (mod 3) of the current state` `        ``ll curSum0 = ((sum0 * zero) + (sum1 * two) + (sum2 * one)) % MOD;` `        ``ll curSum1 = ((sum0 * one) + (sum1 * zero) + (sum2 * two)) % MOD;` `        ``ll curSum2 = ((sum0 * two) + (sum1 * one) + (sum2 * zero)) % MOD;`   `        ``// Update the sum (mod 3) of the previous state` `        ``sum0 = curSum0;` `        ``sum1 = curSum1;` `        ``sum2 = curSum2;` `    ``}`   `    ``// Final answer is stored in sum0` `    ``return` `sum0;` `}`   `// Driver Program` `int` `main()` `{` `    ``ll n = 5;` `    ``ll l = 10;` `    ``ll r = 100;` `    ``cout << totalSubSets(n, l, r);` `    ``return` `0;` `}`

Java

 `import` `java.util.*;`   `public` `class` `Main {` `    ``static` `final` `int` `MOD = ``1000000007``;`   `    ``// Function to return the total number of` `    ``// required sub-sets` `    ``static` `int` `totalSubSets(``long` `n, ``long` `l, ``long` `r) {` `        ``// Variable to store total elements` `        ``// which on dividing by 3 give` `        ``// remainder 0, 1 and 2 respectively` `        ``long` `zero = (``long``)Math.floor((``double``)r / ``3``)` `                ``- (``long``)Math.ceil((``double``)l / ``3``) + ``1``;` `        ``long` `one = (``long``)Math.floor((``double``)(r - ``1``) / ``3``)` `                ``- (``long``)Math.ceil((``double``)(l - ``1``) / ``3``) + ``1``;` `        ``long` `two = (``long``)Math.floor((``double``)(r - ``2``) / ``3``)` `                ``- (``long``)Math.ceil((``double``)(l - ``2``) / ``3``) + ``1``;`   `        ``// Initialize the sum (mod 3) of the previous state` `        ``long` `sum0 = zero, sum1 = one, sum2 = two;`   `        ``// Process for n states and store` `        ``// the sum (mod 3) for 0, 1 and 2` `        ``for` `(``long` `i = ``1``; i < n; ++i) {`   `            ``// Compute the sum (mod 3) of the current state` `            ``long` `curSum0 = ((sum0 * zero) + (sum1 * two) + (sum2 * one)) % MOD;` `            ``long` `curSum1 = ((sum0 * one) + (sum1 * zero) + (sum2 * two)) % MOD;` `            ``long` `curSum2 = ((sum0 * two) + (sum1 * one) + (sum2 * zero)) % MOD;`   `            ``// Update the sum (mod 3) of the previous state` `            ``sum0 = curSum0;` `            ``sum1 = curSum1;` `            ``sum2 = curSum2;` `        ``}`   `        ``// Final answer is stored in sum0` `        ``return` `(``int``)sum0;` `    ``}`   `    ``// Driver Program` `    ``public` `static` `void` `main(String[] args) {` `        ``long` `n = ``5``;` `        ``long` `l = ``10``;` `        ``long` `r = ``100``;` `        ``System.out.println(totalSubSets(n, l, r));` `    ``}` `}`

Python3

 `MOD ``=` `1000000007`   `# Function to calculate the total number of subsets` `def` `totalSubSets(n, l, r):` `     `  `    ``zero ``=` `(r ``/``/` `3``) ``-` `((l ``-` `1``) ``/``/` `3``)` `    ``one ``=` `((r ``-` `1``) ``/``/` `3``) ``-` `((l ``-` `2``) ``/``/` `3``)` `    ``two ``=` `((r ``-` `2``) ``/``/` `3``) ``-` `((l ``-` `3``) ``/``/` `3``)`   `    ``# Initialize the sum ` `    ``sum0 ``=` `zero` `    ``sum1 ``=` `one` `    ``sum2 ``=` `two`   `    ``# Iterate for each index from 1 to n (exclusive)` `    ``for` `i ``in` `range``(``1``, n):` `        ``curSum0 ``=` `((sum0 ``*` `zero) ``+` `(sum1 ``*` `two) ``+` `(sum2 ``*` `one)) ``%` `MOD` `        ``curSum1 ``=` `((sum0 ``*` `one) ``+` `(sum1 ``*` `zero) ``+` `(sum2 ``*` `two)) ``%` `MOD` `        ``curSum2 ``=` `((sum0 ``*` `two) ``+` `(sum1 ``*` `one) ``+` `(sum2 ``*` `zero)) ``%` `MOD`   `        ``# Update the sums for the next iteration` `        ``sum0 ``=` `curSum0` `        ``sum1 ``=` `curSum1` `        ``sum2 ``=` `curSum2`   `    ``return` `sum0`   `# Driver code` `n ``=` `5` `l ``=` `10` `r ``=` `100` `print``(``"Total number of subsets:"``, totalSubSets(n, l, r))`

C#

 `using` `System;`   `public` `class` `Program` `{` `    ``const` `long` `MOD = 1000000007;`   `    ``static` `long` `TotalSubSets(``long` `n, ``long` `l, ``long` `r)` `    ``{` `        ``// Variable to store total elements` `        ``// which on dividing by 3 give` `        ``// remainder 0, 1 and 2 respectively` `        ``long` `zero = (``long``)Math.Floor((``double``)r / 3) - (``long``)Math.Ceiling((``double``)l / 3) + 1;` `        ``long` `one = (``long``)Math.Floor((``double``)(r - 1) / 3) - (``long``)Math.Ceiling((``double``)(l - 1) / 3) + 1;` `        ``long` `two = (``long``)Math.Floor((``double``)(r - 2) / 3) - (``long``)Math.Ceiling((``double``)(l - 2) / 3) + 1;`   `        ``// Initialize the sum (mod 3) of the previous state` `        ``long` `sum0 = zero, sum1 = one, sum2 = two;`   `        ``// Process for n states and store` `        ``// the sum (mod 3) for 0, 1 and 2` `        ``for` `(``long` `i = 1; i < n; ++i)` `        ``{` `            ``// Compute the sum (mod 3) of the current state` `            ``long` `curSum0 = ((sum0 * zero) + (sum1 * two) + (sum2 * one)) % MOD;` `            ``long` `curSum1 = ((sum0 * one) + (sum1 * zero) + (sum2 * two)) % MOD;` `            ``long` `curSum2 = ((sum0 * two) + (sum1 * one) + (sum2 * zero)) % MOD;`   `            ``// Update the sum (mod 3) of the previous state` `            ``sum0 = curSum0;` `            ``sum1 = curSum1;` `            ``sum2 = curSum2;` `        ``}`   `        ``// Final answer is stored in sum0` `        ``return` `(``int``)sum0;` `    ``}`   `    ``public` `static` `void` `Main()` `    ``{` `        ``long` `n = 5;` `        ``long` `l = 10;` `        ``long` `r = 100;` `        ``Console.WriteLine(TotalSubSets(n, l, r));` `    ``}` `}`

Javascript

 `// Function to return the total number of required sub-sets` `function` `totalSubSets(n, l, r) {` `    ``const MOD = 1000000007;`   `    ``// Variable to store total elements` `    ``// which on dividing by 3 give` `    ``// remainder 0, 1, and 2 respectively` `    ``const zero = Math.floor(r / 3) - Math.ceil(l / 3) + 1;` `    ``const one = Math.floor((r - 1) / 3) - Math.ceil((l - 1) / 3) + 1;` `    ``const two = Math.floor((r - 2) / 3) - Math.ceil((l - 2) / 3) + 1;`   `    ``// Initialize the sum (mod 3) of the previous state` `    ``let sum0 = zero, sum1 = one, sum2 = two;`   `    ``// Process for n states and store` `    ``// the sum (mod 3) for 0, 1, and 2` `    ``for` `(let i = 1; i < n; ++i) {`   `        ``// Compute the sum (mod 3) of the current state` `        ``const curSum0 = ((sum0 * zero) + (sum1 * two) + (sum2 * one)) % MOD;` `        ``const curSum1 = ((sum0 * one) + (sum1 * zero) + (sum2 * two)) % MOD;` `        ``const curSum2 = ((sum0 * two) + (sum1 * one) + (sum2 * zero)) % MOD;`   `        ``// Update the sum (mod 3) of the previous state` `        ``sum0 = curSum0;` `        ``sum1 = curSum1;` `        ``sum2 = curSum2;` `    ``}`   `    ``// Final answer is stored in sum0` `    ``return` `sum0;` `}`   `// Driver Program` `    ``const n = 5;` `    ``const l = 10;` `    ``const r = 100;` `    ``console.log(totalSubSets(n, l, r));`

Output:

`80107136`

Time Complexity: O(n)

Auxiliary Space: O(1), since no extra space has been taken.