Algorithm 如何找到大C(n,r)的mod

Algorithm 如何找到大C(n,r)的mod,algorithm,math,combinations,modulo,Algorithm,Math,Combinations,Modulo,如何找到C(n,r)mod k 在哪里 原来的约束条件成立 谢谢。这是动态编程的典型用例。帕斯卡三角形给了我们 C(n, r) = C(n-1, r) + C(n-1, r-1) 我们也知道 C(n, n) = 1 C(n, 0) = 1 C(n, 1) = n 您可以对每个子结果应用模数,以避免溢出。 时间和内存复杂性都是O(n^2)这是动态编程的典型用例。帕斯卡三角形给了我们 C(n, r) = C(n-1, r) + C(n-1, r-1) 我们也知道 C(n, n) = 1 C(n

如何找到C(n,r)mod k 在哪里

原来的约束条件成立


谢谢。

这是动态编程的典型用例。帕斯卡三角形给了我们

C(n, r) = C(n-1, r) + C(n-1, r-1)
我们也知道

C(n, n) = 1
C(n, 0) = 1
C(n, 1) = n
您可以对每个子结果应用模数,以避免溢出。
时间和内存复杂性都是O(n^2)

这是动态编程的典型用例。帕斯卡三角形给了我们

C(n, r) = C(n-1, r) + C(n-1, r-1)
我们也知道

C(n, n) = 1
C(n, 0) = 1
C(n, 1) = n
您可以对每个子结果应用模数,以避免溢出。
时间和内存复杂性都是O(n^2)

我认为,更快的方法是使用模逆

复杂性将低至
log(n)

比如说

ncr(x,y)%m将

a = fac(x) % m;
b = fac(y) % m;
c = fac(x-y) % m;
现在如果您需要计算
(a/b)%m
你可以使用费马的小定理来做
(a%m)*(pow(b,m-2)%m)//


我认为,更快的方法是使用模逆

复杂性将低至
log(n)

比如说

ncr(x,y)%m将

a = fac(x) % m;
b = fac(y) % m;
c = fac(x-y) % m;
现在如果您需要计算
(a/b)%m
你可以使用费马的小定理来做
(a%m)*(pow(b,m-2)%m)//


我知道复杂度为O(r*log\n)的算法 首先看一下不带mod k计算C(n,r)的算法:

int res = 1;
for(int i=1; i<=r; i++){
  res*=(n+1-i);
  res/=i;
}
int res=1;

对于(int i=1;i我知道复杂度为O(r*log\n)的算法 首先看一下不带mod k计算C(n,r)的算法:

int res = 1;
for(int i=1; i<=r; i++){
  res*=(n+1-i);
  res/=i;
}
int res=1;
对于(inti=1;i
C(n,r)=n!/(r!(n-r)!)=(n-r+1)!/r!

由于
k
是素数,对于每个
r
,我们可以使用
O(lgn)
中的扩展欧几里德算法找到其模乘逆
r^-1

因此,您可以将
((n-r+1)!/r)%k计算为
((n-r+1)!%k)*r^-1)%k
。 再重复一遍,你就会得到结果。

由于
k
是素数,对于每个
r
,我们可以使用
O(lgn)
中的扩展欧几里德算法找到其模乘逆
r^-1

因此,您可以将
((n-r+1)!/r)%k计算为
((n-r+1)!%k)*r^-1)%k

重复一遍
1~r
,你就会得到结果。

时间和内存复杂性都是O(n)
。不!这是
O(n^2)
,这太多了。谢谢你抓住了错误。进行了编辑。
时间和内存复杂性都是O(n)
。不!这是
O(n^2)
这太多了。谢谢你抓住了错误。进行了编辑。你能详细解释一下吗?你能详细解释一下吗?