Lucas定理模板

来源:互联网 发布:恒大kk服务器地址端口 编辑:程序博客网 时间:2024/06/06 19:09

Lucas定理是用来求解C(m,n)mod p的值的。其中m和n的值可以很大,p一定是素数。

对阶乘打表的模板

LL quick_mod(LL a, LL b, LL c)//费马小定理+快速幂求逆元  {      LL ans = 1;      while (b)      {          if (b%2==1)              ans = (ans*a) % c;          b /=2;          a = (a*a) % c;      }      return ans;  }      LL fac[MAXN];  void Get_Fac(LL m)//阶乘打表  {      fac[0] = 1;      for (int i = 1; i <= m; i++)          fac[i] = (fac[i - 1] * i) % m;  }  LL Lucas(LL n, LL m, LL p)//卢卡斯定理  {      LL ans = 1;      while (n && m)      {          LL a = n % p;          LL b = m % p;          if (a < b)              return 0;          ans = ((ans*fac[a] % p) * (quick_mod(fac[b] * fac[a - b] % p, p - 2, p))) % p;          n /= p;          m /= p;      }      return ans;  }  


不用对阶乘打表的模板

LL quick_mod(LL a, LL b, LL c)  {LL ans = 1;while (b){if (b % 2 == 1)ans = (ans*a) % c;b /= 2;a = (a*a) % c;}return ans;}LL C(LL n, LL k,LL p) {if (n < k)return 0;if (k > n - k)k = n - k;LL a = 1, b = 1;for (int i = 0; i < k; i++) {a = a * (n - i) % p;b = b * (i + 1) % p;}return a * quick_mod(b, p - 2,p) % p;}LL lucas(LL a, LL b,LL p){if (b == 0)return 1;return C(a % p, b % p,p) * lucas(a / p, b / p,p) % p;}