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

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: 9
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: 1
{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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
#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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


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#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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

chevron_right


PHP

filter_none

edit
close

play_arrow

link
brightness_4
code

<?php
# Php implementation of the approach 
  
# Function to return the total number of 
# required sub-sets 
function totalSubSets($n, $l, $r
      
    $MOD = 1000000007 ;
    // Variable to store total elements 
    // which on dividing by 3 give 
    // remainder 0, 1 and 2 respectively 
    $zero = floor($r / 3) 
            - ceil($l / 3) + 1; 
    $one = floor(($r - 1) / 3) 
            - ceil(($l - 1) / 3) + 1; 
    $two = floor(($r - 2) / 3) 
            - ceil(($l - 2) / 3) + 1; 
  
    // Create a dp table 
    $dp = array() ;
    for($i = 0; $i < $n; $i++)
        for($j = 0; $j < 3; $j++)
            $dp[$i][$j] = 0 ;
              
    $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 = 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 
$n = 5; 
$l = 10; 
$r = 100; 
echo totalSubSets($n, $l, $r); 
      
// This code is contributed by Ryuga
?>

chevron_right


Output:

80107136


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : ihritik, Ryuga, Chandan_Kumar