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 :
C++
// 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.#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 bint 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 factorialsvoid 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 factorialsvoid 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 nCiint comb(int big, int small){Â Â Â Â return (long long)fact[big] * invfact[small] % mod * Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â invfact[big - small] % mod;}Â
// function that returns the count of numbersint 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 Codeint main(){Â Â Â Â int a = 3, b = 4, n = 11028;Â Â Â Â cout << count(a, b, n);Â Â Â Â return 0;} |
Java
// 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 small)     {        return (int) ((long) fact[big] * invfact[small] % mod                * invfact[big - small] % 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 |
Python3
# 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 = 1000000007N = 1000005fact = [0] * Ninvfact = [0] * NÂ
# function to check if sum of# digits is made of a and bdef 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 factorialsdef 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 factorialsdef 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 nCidef comb(big, small):Â Â Â Â Â Â Â Â Â return (fact[big] * invfact[small] % mod *Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â invfact[big - small] % mod)Â
# function that returns the # count of numbersdef 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 Codeif __name__=="__main__":Â Â Â Â a = 3Â Â Â Â b = 4Â Â Â Â n = 11028Â Â Â Â print(count(a, b, n))Â
# This code is contributed # by ChitraNayal |
C#
// 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 small)     {        return (int) ((long) fact[big] * invfact[small] % mod                * invfact[big - small] % 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 |
Javascript
<script>    // JavaScript 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.    const mod = 1000000007;    const N = 1000005;    let fact = new Array(N).fill(0);    let invfact = new Array(N).fill(0);Â
    // function to check if sum of    // digits is made of a and b    const 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 && x % 10 != b)                return 0;Â
            x = Math.floor(x / 10);        }Â
        return 1;    }Â
    // calculate the modInverse V / of a number in O(log n)    const modInverse = (a, m) => {        let m0 = m;        let y = 0, x = 1;Â
        if (m == 1)            return 0;Â
        while (a > 1) {Â
            // q is quotient            let q = Math.floor(a / m);            let 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    const pregenFact = () => {        fact[0] = 1;        fact[1] = 1;        for (let i = 1; i <= 1000000; ++i)            fact[i] = fact[i - 1] * i % mod;    }Â
    // function to pre calculate the    // modInverse of factorials    const pregenInverse = () => {        invfact[0] = 1;        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 (let i = 999999; i > 1; --i)            invfact[i] = (invfact[i + 1] * (i + 1)) % mod;    }Â
    // function that returns the value of nCi    let comb = (big, small) => {        return ((BigInt(fact[big]) * BigInt(invfact[small])) % BigInt(mod) * BigInt(invfact[big - small]) % BigInt(mod)) % BigInt(mod);    }Â
    // function that returns the count of numbers    const 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));Â
        let ans = 0n;        for (let i = 0; i <= n; ++i)            if (check(i * a + (n - i) * b, a, b)) {                ans = (ans + comb(n, i)) % BigInt(mod);            }        return ans;    }Â
    // Driver Code    let a = 3, b = 4, n = 11028;    document.write(count(a, b, n));Â
// This code is contributed by rakeshsahniÂ
</script> |
461668105
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!



