【问题标题】:modular multiplicative inverse of an number for calculating nCr % 10000007 (combination)用于计算 nCr % 10000007 的数的模乘逆(组合)
【发布时间】:2019-12-11 12:22:19
【问题描述】:

我正在尝试计算 nCr % M。所以我正在做的是

nCr = n!/(n-r)!*r! %M

换句话说,nCr = n! * (inverseFactorial(n-r)*inverseFactorial(r))。 所以我正在预先计算从 1 到 10^5 范围内的数字的阶乘和逆因子的值。 基本上,我正在尝试实现第一个答案。

https://www.quora.com/How-do-I-find-the-value-of-nCr-1000000007-for-the-large-number-n-n-10-6-in-C

这是我的代码。

        //fill fact
        fact[0]=1;
        for(int i=1;i<100001;i++){
            fact[i]=fact[i-1]*i%1000000007;
            //fact[i]=fact[i]%1000000007;
        }

        //fill ifact - inverse of fact
        ifact[0]=1;
        for(int i=1;i<100001;i++){
            ifact[i] = ifact[i-1]*inverse(i)%1000000007;
            //ifact[i]=ifact[i]%1000000007;
        }

方法是

public static long fastcomb(int n,int r){

        long ans = ifact[r]*ifact[n-r];
        System.out.println(ifact[r]);
        System.out.println(ifact[n-r]);
        ans = ans%1000000007;
        ans=ans*fact[n];
        System.out.println(fact[n]);
        ans = ans%1000000007;
        return ans;

    }


 public static int modul(int x){
        x = x%1000000007;
        if(x<0){
            x+=1000000007;
        }
        return x;
    }

public static int inverse(int x){
    int mod = modul(x);
    if(mod==1){
        return 1;
    }

    return modul((-1000000007/mod)*(ifact[1000000007%mod]%1000000007));

}

我不确定我哪里出错了?请帮助我做错了什么,因为 ifact[2] 它向我显示 500000004。

【问题讨论】:

  • 做同样的事情,但对于具有小素数的小 nCr 作为模数和调试!
  • 注意2 * 500000004 % p = 1,所以5000000042的倒数。不是你要计算的吗?

标签: algorithm data-structures combinations modulo factorial


【解决方案1】:

这是乘法逆的费马小定理实现。 我测试了它,它可以工作。

   static long modInverse(long a, long m)
   {
         return power(a, m - 2, m);
   }

   // To compute x^y under modulo m
   static long power(long x, long y, long m)
   {
      if (y == 0)
         return 1;

      long p = power(x, y / 2, m) % m;
      p = (p * p) % m;

      if (y % 2 == 0)
         return p;
      else
         return (x * p) % m;
   } 

我正在研究 nCr mod M,你不需要那个数组来找到它。

找到以下 nCr mod m 的实现,请检查你的值,记住 m 应该是这个方法的素数。

   static long nCr_mod_m(long n, long r, long m)
   {
      if(n-r < r) r = (n-r);    //  since nCr = nC(n-r)

      long top_part = n, bottom_part=1;

      for(long i=1; i<r; i++)
         top_part = (top_part*(n-i)) % m;

      for(long i=2; i<=r; i++)
         bottom_part = (bottom_part * modInverse(i, m))%m;

      return (top_part*bottom_part)%m;

   }

【讨论】:

  • 感谢您的快速回复。我正在使用数组,这样我就不需要一次又一次地计算 top_part 和 bottom_part。这可以使用数组来完成吗,我正在使用上面提到的 modinverse。并得到正确的逆值,但在计算 3C2 时,我得到 -294967265。我的意思是我的 fastcomb 方法有什么问题吗?
  • 我的方法能给出正确答案吗?我可以考虑改进它。如果我的答案暂时有效,请不要忘记接受作为答案,
  • 这段代码没有优化,简单易懂。
  • 我没有测试 nCr_mod_m 部分,但 inverse 工作正常。我的fastcomb方法有问题吗?
  • 您的“int inverse(int x)”方法背后的理论是什么?我正在尝试先了解逻辑。
猜你喜欢
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多