给定a,b和N(1至10 6 )。任务是对由数字a和b形成的数字精确地长度为N的计数,以使如此形成的数字的数字总和也仅包含数字a和b。由于计数可能非常大,因此请打印计数%1000000007。
例子 :
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
方法:由于N非常大,我们无法迭代所有数字以单独检查它们。由于数字的长度为N,并且由两位a和b组成,所以a将占据i位置,b将占据n – i位置。因此,数字的总和为(a * i +(ni)* b) 。我们可以检查从0到N的所有i的数字和是否由a和b组成。因此,形成的数字总数为它对应于由a和b构成的数字的所有组合,其数字之和也由a和b构成。
在计算中实施模块化运算:
计算满足给定条件的从0到N的所有i的%1000000007。
一个简单的解决方案将给出答案:
(factorial(n) * modInverse(n - i) * modInverse(i)) % mod
由于计算modInverse需要O(log N),因此,如果预先计算了所有阶乘,则总时间复杂度将为O(N log N)。
一个有效的解决方案是预先计算所有阶乘直到N。计算N!的modInverse。在O(log N)中,从(N – 1)计算所有阶乘的modInverse!到1!由下面给出的公式。
modInverse(i!) = modInverse((i + 1)!) * (i + 1)
下面是上述方法的实现:
C++
// 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
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;
}
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 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
Python 3
# 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
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 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
输出:
461668105