我只是看到了这个问题,却不知道如何解决。您能给我提供算法,C ++代码或想法吗?
这是一个非常简单的问题。给定N和K的值,您需要告诉我们二项式系数C(N,K)的值。您可以放心,K <= N,并且N的最大值是1,000,000,000,000,000。由于该值可能非常大,因此您需要以1009为模来计算结果。输入 输入的第一行包含测试用例T的数量,最多为1000。接下来的T行中的每一行都由两个以空格分隔的整数N和K组成,其中0 <= K <= N和1 <= N <= 1,000,000,000,000,000 。输出量 对于每个测试用例,在新行上打印二项式系数C(N,K)以1009为模的值。 输入: 3 3 1 5 2 10 3 输出: 3 10 120
这是一个非常简单的问题。给定N和K的值,您需要告诉我们二项式系数C(N,K)的值。您可以放心,K <= N,并且N的最大值是1,000,000,000,000,000。由于该值可能非常大,因此您需要以1009为模来计算结果。输入
输入的第一行包含测试用例T的数量,最多为1000。接下来的T行中的每一行都由两个以空格分隔的整数N和K组成,其中0 <= K <= N和1 <= N <= 1,000,000,000,000,000 。输出量
对于每个测试用例,在新行上打印二项式系数C(N,K)以1009为模的值。
输入: 3 3 1 5 2 10 3
输出: 3 10 120
注意1009是质数。
现在您可以使用卢卡斯定理。
哪个状态:
Let p be a prime. If n = a1a2...ar when written in base p and if k = b1b2...br when written in base p (pad with zeroes if required) Then (n choose k) modulo p = (a1 choose b1) * (a2 choose b2) * ... * (ar choose br) modulo p. i.e. remainder of n choose k when divided by p is same as the remainder of the product (a1 choose b1) * .... * (ar choose br) when divided by p. Note: if bi > ai then ai choose bi is 0.
这样,您的问题就减少了,可以找到最多为a的选择b形式为a <= 1009和b <= 1009的对数N / log 1009数字(以1009为基的N的位数)的乘积1009。
即使N接近10 ^ 15,这也应该使它更容易。
注意: 对于N = 10 ^ 15,N选择N / 2大于2 ^(100000000000000),这远远超出了无符号长整型。 同样,卢卡斯定理建议的算法为O(log N),这 exponentially比尝试直接计算二项式系数要快(即使您做了mod 1009来处理溢出问题)。
注意:
对于N = 10 ^ 15,N选择N / 2大于2 ^(100000000000000),这远远超出了无符号长整型。
同样,卢卡斯定理建议的算法为O(log N),这 exponentially比尝试直接计算二项式系数要快(即使您做了mod 1009来处理溢出问题)。
exponentially
这是我很久以前写的关于二项式的一些代码,您需要做的就是对其进行修改,以进行1009模运算(可能有错误,不一定是推荐的编码样式):
class Binomial { public: Binomial(int Max) { max = Max+1; table = new unsigned int * [max](); for (int i=0; i < max; i++) { table[i] = new unsigned int[max](); for (int j = 0; j < max; j++) { table[i][j] = 0; } } } ~Binomial() { for (int i =0; i < max; i++) { delete table[i]; } delete table; } unsigned int Choose(unsigned int n, unsigned int k); private: bool Contains(unsigned int n, unsigned int k); int max; unsigned int **table; }; unsigned int Binomial::Choose(unsigned int n, unsigned int k) { if (n < k) return 0; if (k == 0 || n==1 ) return 1; if (n==2 && k==1) return 2; if (n==2 && k==2) return 1; if (n==k) return 1; if (Contains(n,k)) { return table[n][k]; } table[n][k] = Choose(n-1,k) + Choose(n-1,k-1); return table[n][k]; } bool Binomial::Contains(unsigned int n, unsigned int k) { if (table[n][k] == 0) { return false; } return true; }