Count numbers formed by given two digit with sum having given digits

Given a, b and N(1 to 106). Task is to count the numbers formed by digits a and b exactly of a length N such that the sum of the digits of the number thus formed also contains digits a and b only. Since the count can be very large, print the count % 1000000007.

Examples :

Input : a = 1 b = 3 n = 3 
Output : 1 
Explanation : The only number is 111 of length 3,
the sum of digits of 111 is 3, which is b. 

Input : a = 6 b = 9 n = 1
Output : 2
Explanation : The numbers of length 1 is 6 and 9,
whose sum of digits is 6 and 9 respectively which
is a and b respectively.

Input: a = 2 b = 3 n = 10
Output : 165   

Approach: Since N is very large, we cannot iterate for all numbers to check them individually. As the number is of length N and formed by two digits a and b, a will occupy i positions and b will occupy n – i positions. The sum of digits thus will be ( a*i + (n-i)*b ). We can check if the sum of digits is formed of a and b for all i ranging from 0 to N. Thus, the total count of numbers formed will be which will correspond to all combination of numbers formed by a and b whose sum of digits is also formed of a and b.

Implement Modular Operations in calculations :
Calculate %1000000007 for all i ranging from 0 to N satisfying the given condition.

A simple solution will give answer as :



(factorial(n) * modInverse(n - i) * modInverse(i)) % mod

Since calculating the modInverse takes O(log N), the total time complexity will be O(N log N), if all the factorials are pre-calculated.

An efficient solution will be to precalculate all the factorials till N. Calculate the modInverse of N! in O(log N) and calculate the modInverse of all factorials from (N – 1)! to 1! by the given below formula.

modInverse(i!) = modInverse((i + 1)!) * (i + 1)

Below is the implementation of the above approach :

filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
#include <bits/stdc++.h>
using namespace std;
  
const int mod = 1e9 + 7;
const int N = 1000005;
int fact[N], invfact[N];
  
// function to check if sum of
// digits is made of a and b
int check(int x, int a, int b)
{
    // sum of digits is 0
    if (x == 0)
        return 0;
  
    while (x) {
  
        // if any of digits in sum is
        // other than a and b
        if (x % 10 != a and x % 10 != b)
            return 0;
  
        x /= 10;
    }
  
    return 1;
}
  
// calculate the modInverse V / of a number in O(log n)
int modInverse(int a, int m)
{
    int m0 = m;
    int y = 0, x = 1;
  
    if (m == 1)
        return 0;
  
    while (a > 1) {
  
        // q is quotient
        int q = a / m;
        int t = m;
  
        // m is remainder now, process
        // same as Euclid's algo
        m = a % m, a = t;
        t = y;
  
        // Update y and x
        y = x - q * y;
        x = t;
    }
  
    // Make x positive
    if (x < 0)
        x += m0;
  
    return x;
}
  
// function to pregenerate factorials
void pregenFact()
{
    fact[0] = fact[1] = 1;
    for (int i = 1; i <= 1000000; ++i)
        fact[i] = (long long)fact[i - 1] * i % mod;
}
  
// function to pre calculate the
// modInverse of factorials
void pregenInverse()
{
    invfact[0] = invfact[1] = 1;
  
    // calculates the modInverse of the last factorial
    invfact[1000000] = modInverse(fact[1000000], mod);
  
    // precalculates the modInverse of all factorials
    // by formulae
    for (int i = 999999; i > 1; --i)
        invfact[i] = ((long long)invfact[i + 1] * 
                      (long long)(i + 1)) % mod;
}
  
// function that returns the value of nCi
int comb(int big, int smal)
{
    return (long long)fact[big] * invfact[smal] % mod * 
                              invfact[big - smal] % mod;
}
  
// function that returns the count of numbers
int count(int a, int b, int n)
{
    // function call to pre-calculate the
    // factorials and modInverse of factorials
    pregenFact();
    pregenInverse();
  
    // if a and b are same
    if (a == b) 
        return (check(a * n, a, b));
  
    int ans = 0;
    for (int i = 0; i <= n; ++i) 
        if (check(i * a + (n - i) * b, a, b)) 
            ans = (ans + comb(n, i)) % mod;
    return ans;
}
  
// Driver Code
int main()
{
    int a = 3, b = 4, n = 11028;
    cout << count(a, b, n);
    return 0;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
  
class GFG 
{
  
    static int mod = (int) (1e9 + 7);
    static int N = 1000005;
    static int fact[] = new int[N], invfact[] = new int[N];
  
    // function to check if sum of
    // digits is made of a and b
    static int check(int x, int a, int b) 
    {
        // sum of digits is 0
        if (x == 0
        {
            return 0;
        }
  
        while (x > 0
        {
  
            // if any of digits in sum is
            // other than a and b
            if (x % 10 != a & x % 10 != b)
            {
                return 0;
            }
  
            x /= 10;
        }
  
        return 1;
    }
  
    // calculate the modInverse V / of a number in O(log n)
    static int modInverse(int a, int m)
    {
        int m0 = m;
        int y = 0, x = 1;
        if (m == 1
        {
            return 0;
        }
  
        while (a > 1
        {
  
            // q is quotient
            int q = a / m;
            int t = m;
  
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
  
            // Update y and x
            y = x - q * y;
            x = t;
        }
  
        // Make x positive
        if (x < 0
        {
            x += m0;
        }
  
        return x;
    }
  
    // function to pregenerate factorials
    static void pregenFact() 
    {
        fact[0] = fact[1] = 1;
        for (int i = 1; i <= 1000000; ++i) 
        {
            fact[i] = (int) ((long) fact[i - 1] * i % mod);
        }
    }
  
    // function to pre calculate the
    // modInverse of factorials
    static void pregenInverse()
    {
        invfact[0] = invfact[1] = 1;
  
        // calculates the modInverse of 
        // the last factorial
        invfact[1000000] = modInverse(fact[1000000], mod);
  
        // precalculates the modInverse of 
        // all factorials by formulae
        for (int i = 999999; i > 1; --i) 
        {
            invfact[i] = (int) (((long) invfact[i + 1]
                    * (long) (i + 1)) % mod);
        }
    }
  
    // function that returns the value of nCi
    static int comb(int big, int smal) 
    {
        return (int) ((long) fact[big] * invfact[smal] % mod
                * invfact[big - smal] % mod);
    }
  
    // function that returns the count of numbers
    static int count(int a, int b, int n) 
    {
          
        // function call to pre-calculate the
        // factorials and modInverse of factorials
        pregenFact();
        pregenInverse();
  
        // if a and b are same
        if (a == b)
        {
            return (check(a * n, a, b));
        }
  
        int ans = 0;
        for (int i = 0; i <= n; ++i) 
        {
            if (check(i * a + (n - i) * b, a, b) == 1)
            {
                ans = (ans + comb(n, i)) % mod;
            }
        }
        return ans;
    }
  
    // Driver Code
    public static void main(String[] args) 
    {
        int a = 3, b = 4, n = 11028;
        System.out.println(count(a, b, n));
    }
  
// This code is contributed by PrinciRaj1992
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 program to count the 
# number of numbers formed by 
# digits a and b exactly of a 
# length N such that the sum of 
# the digits of the number thus 
# formed is of digits a and b.
  
mod = 1000000007
N = 1000005
fact = [0] * N
invfact = [0] * N
  
# function to check if sum of
# digits is made of a and b
def check(x, a, b):
  
    # sum of digits is 0
    if (x == 0):
        return 0
  
    while (x) :
  
        # if any of digits in sum 
        # is other than a and b
        if (x % 10 != a and x % 10 != b):
            return 0
  
        x //= 10
  
    return 1
  
# calculate the modInverse V of
# a number in O(log n)
def modInverse(a, m):
  
    m0 = m
    y = 0
    x = 1
  
    if (m == 1):
        return 0
  
    while (a > 1) :
  
        # q is quotient
        q = a // m
        t = m
  
        # m is remainder now, process
        # same as Euclid's algo
        m = a % m
        a = t
        t = y
  
        # Update y and x
        y = x - q * y
        x = t
  
    # Make x positive
    if (x < 0):
        x += m0
  
    return x
  
# function to pregenerate factorials
def pregenFact():
  
    fact[0] = fact[1] = 1
    for i in range(1, 1000001):
        fact[i] = fact[i - 1] * i % mod
  
# function to pre calculate the
# modInverse of factorials
def pregenInverse():
      
    invfact[0] = invfact[1] = 1
  
    # calculates the modInverse of
    # the last factorial
    invfact[1000000] = modInverse(fact[1000000], mod)
  
    # precalculates the modInverse 
    # of all factorials by formulae
    for i in range(999999, 0, -1):
        invfact[i] = ((invfact[i + 1] * 
                      (i + 1)) % mod)
  
# function that returns
# the value of nCi
def comb(big, smal):
      
    return (fact[big] * invfact[smal] % mod * 
                        invfact[big - smal] % mod)
  
# function that returns the 
# count of numbers
def count(a, b, n):
      
    # function call to pre-calculate 
    # the factorials and modInverse 
    # of factorials
    pregenFact()
    pregenInverse()
  
    # if a and b are same
    if (a == b) :
        return (check(a * n, a, b))
  
    ans = 0
    for i in range(n + 1) :
        if (check(i * a + (n - i) * b, a, b)) :
            ans = (ans + comb(n, i)) % mod
    return ans
  
# Driver Code
if __name__=="__main__":
    a = 3
    b = 4
    n = 11028
    print(count(a, b, n))
  
# This code is contributed 
# by ChitraNayal
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to count the number
// of numbers formed by digits a
// and b exactly of a length N such
// that the sum of the digits of the
// number thus formed is of digits a and b.
using System;
  
class GFG 
{
  
    static int mod = (int) (1e9 + 7);
    static int N = 1000005;
    static int []fact = new int[N];
    static int []invfact = new int[N];
  
    // function to check if sum of
    // digits is made of a and b
    static int check(int x, int a, int b) 
    {
        // sum of digits is 0
        if (x == 0) 
        {
            return 0;
        }
  
        while (x > 0) 
        {
  
            // if any of digits in sum is
            // other than a and b
            if (x % 10 != a & x % 10 != b)
            {
                return 0;
            }
  
            x /= 10;
        }
  
        return 1;
    }
  
    // calculate the modInverse V / of a number in O(log n)
    static int modInverse(int a, int m)
    {
        int m0 = m;
        int y = 0, x = 1;
        if (m == 1) 
        {
            return 0;
        }
  
        while (a > 1) 
        {
  
            // q is quotient
            int q = a / m;
            int t = m;
  
            // m is remainder now, process
            // same as Euclid's algo
            m = a % m;
            a = t;
            t = y;
  
            // Update y and x
            y = x - q * y;
            x = t;
        }
  
        // Make x positive
        if (x < 0) 
        {
            x += m0;
        }
  
        return x;
    }
  
    // function to pregenerate factorials
    static void pregenFact() 
    {
        fact[0] = fact[1] = 1;
        for (int i = 1; i <= 1000000; ++i) 
        {
            fact[i] = (int) ((long) fact[i - 1] * i % mod);
        }
    }
  
    // function to pre calculate the
    // modInverse of factorials
    static void pregenInverse()
    {
        invfact[0] = invfact[1] = 1;
  
        // calculates the modInverse of 
        // the last factorial
        invfact[1000000] = modInverse(fact[1000000], mod);
  
        // precalculates the modInverse of 
        // all factorials by formulae
        for (int i = 999999; i > 1; --i) 
        {
            invfact[i] = (int) (((long) invfact[i + 1]
                    * (long) (i + 1)) % mod);
        }
    }
  
    // function that returns the value of nCi
    static int comb(int big, int smal) 
    {
        return (int) ((long) fact[big] * invfact[smal] % mod
                * invfact[big - smal] % mod);
    }
  
    // function that returns the count of numbers
    static int count(int a, int b, int n) 
    {
          
        // function call to pre-calculate the
        // factorials and modInverse of factorials
        pregenFact();
        pregenInverse();
  
        // if a and b are same
        if (a == b)
        {
            return (check(a * n, a, b));
        }
  
        int ans = 0;
        for (int i = 0; i <= n; ++i) 
        {
            if (check(i * a + (n - i) * b, a, b) == 1)
            {
                ans = (ans + comb(n, i)) % mod;
            }
        }
        return ans;
    }
  
    // Driver Code
    public static void Main(String[] args) 
    {
        int a = 3, b = 4, n = 11028;
        Console.WriteLine(count(a, b, n));
    }
}
  
// This code has been contributed by 29AjayKumar
chevron_right

Output:
461668105

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Recommended Posts:


Striver(underscore)79 at Codechef and codeforces D

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.



Article Tags :