Open In App

Count all Arrays within a Range and Divisible by 3

Given three integers n,l,r, the task is to determine the count of such arrays that follow the below two conditions:

  1. All the elements of the array are between l to r (inclusive)
  2. The sum of all the elements is divisible by 3.

Since the answer can be very long, print the remainder when the result is divided by 1e9+7.



Example:

Input: n=2, l=1, r=3
Output: 3 1
Explanation: [1,2][2,1][3,3]



Input: n = 3, l = 2, r = 2
Output: 1

Approach:

The intuition behind the solution is based on modular arithmetic and dynamic programming.

Here’s a detailed explanation:

Modular Arithmetic: Since we need the sum of the array to be divisible by 3, we don’t care about the actual numbers themselves, but their remainder when divided by 3. This means we’re interested in how many numbers x exists such that x mod 3 equals 0, 1, or 2. We can count these numbers using simple formulas. For example, to count the number of x with a remainder of 1 when divided by 3 (i.e., x = 3k + 1 for some integer k), we can create an inequality l ≤ 3k + 1 ≤ r, simplify it to ceil((l-1)/3) ≤ k ≤ floor((r-1)/3), and then count the number of such k.

Dynamic Programming: After counting all the numbers, we can solve the problem using dynamic programming. We define dp[i][j] as the number of ways to form an array with i numbers such that the sum of these numbers modulo 3 equals j. There are O(n) states (since i can range from 0 to n and j can range from 0 to 2), and we can transition between states by adding a number to the array. The final answer will be at dp[n][0], which represents the number of ways to form an array of length n such that the sum of the numbers is divisible by 3.

The recurrence relation is:

dp[i][(j + k) % 3] = (dp[i][(j + k) % 3] + dp[i – 1][j] * cnt[k]) % MOD

This recurrence relation is used to fill the dynamic programming table dp. Here’s what it represents:

  • dp[i][(j + k) % 3] is the current state, representing the number of arrays of length i where the sum of the elements has a remainder of (j + k) % 3 when divided by 3.
  • dp[i][(j + k) % 3] is updated by adding the number of arrays of length i – 1 where the sum of the elements has a remainder of j when divided by 3, multiplied by the count of numbers that have a remainder of k when divided by 3 (cnt[k]).

Steps-by-step approach:

Below is the implementation of the above approach:




#include <bits/stdc++.h>
using namespace std;
 
// Define the modulus for the problem
const int MOD = 1e9 + 7;
 
// Initialize the dynamic programming table and the count
// array
long long dp[200005][3], cnt[3];
 
void solve(int n, int l, int r)
{
    // Count the numbers between l and r that have a
    // remainder of 0, 1, or 2 when divided by 3
    for (int i = 0; i < 3; ++i) {
        cnt[i] = (r - i + 3) / 3 - (l - 1 - i + 3) / 3;
    }
 
    // Initialize the dynamic programming table
    dp[0][0] = 1;
 
    // Fill the dynamic programming table
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < 3; ++j) {
            for (int k = 0; k < 3; ++k) {
                dp[i][(j + k) % 3]
                    = (dp[i][(j + k) % 3]
                       + 1LL * dp[i - 1][j] * cnt[k])
                      % MOD;
            }
        }
    }
 
    // Print the number of arrays where the sum of the
    // elements is divisible by 3
    cout << dp[n][0] << endl;
}
 
int main()
{
    // Variables for the length of the array and the range
    // of the elements
    long long n = 2, l = 1, r = 3;
 
    solve(n,l,r);
 
    return 0;
}




public class GFG {
 
    // Define the modulus for the problem
    private static final int MOD = 1000000007;
 
    // Initialize the dynamic programming table and the count array
    private static long[][] dp = new long[200005][3];
    private static long[] cnt = new long[3];
 
    private static void solve(long n, long l, long r) {
        // Count the numbers between l and r that have a
        // remainder of 0, 1, or 2 when divided by 3
        for (int i = 0; i < 3; ++i) {
            cnt[i] = (r - i + 3) / 3 - (l - 1 - i + 3) / 3;
        }
 
        // Initialize the dynamic programming table
        dp[0][0] = 1;
 
        // Fill the dynamic programming table
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < 3; ++j) {
                for (int k = 0; k < 3; ++k) {
                    dp[i][(j + k) % 3] = (dp[i][(j + k) % 3]
                            + (dp[i - 1][j] * cnt[k]) % MOD) % MOD;
                }
            }
        }
 
        // Print the number of arrays where the sum of the
        // elements is divisible by 3
        System.out.println(dp[(int) n][0]);
    }
 
    public static void main(String[] args) {
        // Variables for the length of the array and the range
        // of the elements
        long n = 2, l = 1, r = 3;
 
        solve(n, l, r);
    }
}




# Define the modulus for the problem
MOD = 10**9 + 7
 
# Initialize the dynamic programming table and the count array
dp = [[0] * 3 for _ in range(200005)]
cnt = [0] * 3
 
def solve(n, l, r):
    global dp, cnt
 
    # Count the numbers between l and r that have a remainder
    # of 0, 1, or 2 when divided by 3
    for i in range(3):
        cnt[i] = (r - i + 3) // 3 - (l - 1 - i + 3) // 3
 
    # Initialize the dynamic programming table
    dp[0][0] = 1
 
    # Fill the dynamic programming table
    for i in range(1, n + 1):
        for j in range(3):
            for k in range(3):
                dp[i][(j + k) % 3] = (dp[i][(j + k) % 3] + dp[i - 1][j] * cnt[k]) % MOD
 
    # Print the number of arrays where the sum of the elements is divisible by 3
    print(dp[n][0])
 
if __name__ == "__main__":
    # Variables for the length of the array and the range of the elements
    n = 2
    l = 1
    r = 3
 
    solve(n, l, r)




using System;
 
public class GFG
{
    // Define the modulus for the problem
    private const int MOD = 1000000007;
 
    // Initialize the dynamic programming table and the count array
    private static long[,] dp = new long[200005, 3];
    private static long[] cnt = new long[3];
 
    private static void Solve(long n, long l, long r)
    {
        // Count the numbers between l and r that have a
        // remainder of 0, 1, or 2 when divided by 3
        for (int i = 0; i < 3; ++i)
        {
            cnt[i] = (r - i + 3) / 3 - (l - 1 - i + 3) / 3;
        }
 
        // Initialize the dynamic programming table
        dp[0, 0] = 1;
 
        // Fill the dynamic programming table
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 0; j < 3; ++j)
            {
                for (int k = 0; k < 3; ++k)
                {
                    dp[i, (j + k) % 3] = (dp[i, (j + k) % 3]
                            + (dp[i - 1, j] * cnt[k]) % MOD) % MOD;
                }
            }
        }
 
        // Print the number of arrays where the sum of the
        // elements is divisible by 3
        Console.WriteLine(dp[n, 0]);
    }
 
    public static void Main(string[] args)
    {
        // Variables for the length of the array and the range
        // of the elements
        long n = 2, l = 1, r = 3;
 
        Solve(n, l, r);
    }
}




const MOD = 1e9 + 7;
// Function to solve the problem
function GFG(n, l, r) {
    // Initialize the dynamic programming table and count array
    let dp = new Array(200005).fill(0).map(() => new Array(3).fill(0));
    let cnt = Array(3).fill(0);
    for (let i = 0; i < 3; ++i) {
        cnt[i] = Math.floor((r - i + 3) / 3) - Math.floor((l - 1 - i + 3) / 3);
    }
    // Initialize the dynamic programming table
    dp[0][0] = 1;
    // Fill the dynamic programming table
    for (let i = 1; i <= n; ++i) {
        for (let j = 0; j < 3; ++j) {
            for (let k = 0; k < 3; ++k) {
                dp[i][(j + k) % 3] = (dp[i][(j + k) % 3] + (dp[i - 1][j] * cnt[k]) % MOD) % MOD;
            }
        }
    }
    // Print the number of the arrays where the sum of elements is divisible by 3
    console.log(dp[n][0]);
}
// Main function
function main() {
    // Variables for the length of the array and the range ofelements
    let n = 2, l = 1, r = 3;
    GFG(n, l, r);
}
main();

Output
3

Time Complexity: O(n)
Auxiliary Space: O(n)


Article Tags :