组合数取模(逆元+快速幂(转)

组合数公式:

我们需要求阶乘和逆元阶乘

我们就用1e9+7来求余吧

费马小定理

a^(p-1) ≡1 (mod p)

两边同除以a

a^(p-2) ≡1/a (mod p)

数论1/a 是inv(a)

应该写a^(p-2) ≡ inv(a) (mod p)

所以inv(a) = a^(p-2) (mod p)

这个用快速幂求一下,复杂度O(logn)

引用其他人写的一句话

除法求模不能类似乘法,对于(A/B)mod C,直接(A mod C)/ (B mod C)是错误的;找到B的逆元b(b=B^-1);求出(A*b)modC即可;

由费马小定理:B 关于 P 的逆元为  B^(p-2);

费马小定理(Fermat Theory)是数论中的一个重要定理,其内容为: 假如p是质数,且gcd(a,p)=1,那么 a(p-1)≡1(mod p)。即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。所以,a^-1*a=1=a^(p-1),所以:a^-1=a^(p-2);
数学排列组合公式:C(n,m)= n!/(m!*(n-m)!)

/////////////////////////////////////////////////////////////////////////////////////////////////////

LL pow_mod(LL a, LL b, LL p){//a的b次方求余p                        /
LL ret = 1;                                                                                    
while(b){
if(b & 1) ret = (ret * a) % p;
a = (a * a) % p;
b >>= 1;
}
return ret;
}
LL Fermat(LL a, LL p){//费马求a关于b的逆元
return pow_mod(a, p-2, p);
}

/////////////////////////////////////////////////////////////////////////////////////////////////

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. #define LL long long
  6. #define G 1100000
  7. #define mod 1000003
  8. LL pri[G];
  9. LL ni[G],ans;
  10. LL pow(LL a,int b)
  11. {
  12. LL ans=1,base=a;
  13. while (b>0)
  14. {
  15. if (b%2==1)
  16. ans=(base*ans)%mod;
  17. base=(base*base)%mod;
  18. b/=2;
  19. }
  20. return ans;
  21. }
  22. void s() //打表
  23. {
  24. pri[0]=1;
  25. ni[0]=1;
  26. for (int i=1;i<G ;i++)
  27. {
  28. pri[i]=pri[i-1]*i%mod; //N!
  29. ni[i]=pow(pri[i],mod-2);
  30. }
  31. }
  32. int main()
  33. {
  34. s();
  35. int t,n,b,k=1;
  36. scanf("%d",&t);
  37. while (t--)
  38. {
  39. scanf("%d%d",&n,&b);
  40. ans=((pri[n]*ni[b]%mod)*ni[n-b])%mod; // C(n,m)= n!/(m!*(n-m)!)//就是上面公式的表示
  41. printf("Case %d: %lld\n",k++,ans);
  42. }
  43. return 0;
  44. }

2019.2.22

一只现在很饱的猴猴

原文地址:https://www.cnblogs.com/pipihoudewo/p/10420625.html

时间: 2024-08-05 09:28:15

组合数取模(逆元+快速幂(转)的相关文章

HDU 5698 大组合数取模(逆元)

瞬间移动 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1215    Accepted Submission(s): 600 Problem Description 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几

取模性质,快速幂,快速乘,gcd和最小公倍数

一.取模运算 取模(取余)运算法则: 1. (a+b)%p=(a%p+b%p)%p; 2.(a-b)%p=(a%p-b%p)%p; 3.(a*b)%p=(a%p * b%p)%p; 4.(a^b)%p=(   (a%p)^b  )%p; 5. (  (a+b)%p+c  )%p=( a+(b+c)%p  )%p; 6.( a*(b*c)%p )%p =( c*(a*b)%p )%p; 7.( (a+b)%p*c )%p= ( (a*c)%p + (b*c)%p )%p; 几条重要性质: 1.a≡

[组合数取模-逆元计算模板] zoj 3624 Count Path Pair

思路: 正难则反 //C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q,M); 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"stack" #include"algorithm" #include"iostream" using

组合数取模Lucas定理及快速幂取模

组合数取模就是求的值,根据,和的取值范围不同,采取的方法也不一样. 下面,我们来看常见的两种取值情况(m.n在64位整数型范围内) (1)  , 此时较简单,在O(n2)可承受的情况下组合数的计算可以直接用杨辉三角递推,边做加法边取模. (2) ,   ,并且是素数 本文针对该取值范围较大又不太大的情况(2)进行讨论. 这个问题可以使用Lucas定理,定理描述: 其中 这样将组合数的求解分解为小问题的乘积,下面考虑计算C(ni, mi) %p. 已知C(n, m) mod p = n!/(m!(

hdu 3037 Saving Beans 组合数取模模板题。。

Saving Beans Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2707    Accepted Submission(s): 1014 Problem Description Although winter is far away, squirrels have to work day and night to save b

[BZOJ 3129] [Sdoi2013] 方程 【容斥+组合数取模+中国剩余定理】

题目链接:BZOJ - 3129 题目分析 使用隔板法的思想,如果没有任何限制条件,那么方案数就是 C(m - 1, n - 1). 如果有一个限制条件是 xi >= Ai ,那么我们就可以将 m 减去 Ai - 1 ,相当于将这一部分固定分给 xi,就转化为无限制的情况了. 如果有一些限制条件是 xi <= Ai 呢?直接来求就不行了,但是注意到这样的限制不超过 8 个,我们可以使用容斥原理来求. 考虑容斥:考虑哪些限制条件被违反了,也就是说,有哪些限制为 xi <= Ai 却是 xi

Lucas定理--大组合数取模 学习笔记

维基百科:https://en.wikipedia.org/wiki/Lucas%27_theorem?setlang=zh 参考:http://blog.csdn.net/pi9nc/article/details/9615359 http://hi.baidu.com/lq731371663/item/d7261b0b26e974faa010340f http://hi.baidu.com/j_mat/item/8e3a891c258c4fe9dceecaba 综合以上参考,我做的一下总结:

toj 4111 组合数取模 暴力分解

题目大意:组合数取模,n和m并不算大,p比较大且是合数. 思路:暴力分解+快速幂 注:暴力也是有区别的,分解质因数时可以用以下work函数,写的非常巧妙,摘录自互联网. 1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 5 typedef long long ll; 6 const ll mod = 1ll << 32; 7 const int N = 1000001; 8 const

Luogu P1226 取余运算||快速幂(数论,分治)

P1226 取余运算||快速幂 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 输入格式: 三个整数b,p,k. 输出格式: 输出"b^p mod k=s" s为运算结果 输入输出样例 输入样例#1: 2 10 9 输出样例#1: 2^10 mod 9=7 这是一道很有趣的水题,如果知道公式. 一般求解会溢出,导致答案错误. 这里介绍取模的一个公式: a*b%k=(a%k)*(b%k)%k. 在我们这道题中是b^p = (b^(p/

组合数取模终极版

以前讲述过很多组合数取模问题,详见:http://blog.csdn.net/acdreamers/article/details/8037918 今天,我们继续学习一些稍有难度的组合数取模问题,比如大组合数对合数取模,求大组合数的最后位数字等等. 首先来看组合数对合数取模问题 问题:求的值,其中和,并且是合数. 分析:先把素因子分解,然后转化为求,这里为素数,然后用CRT合并.所以现在重点来研究 如何求的值.这个问题AekdyCoin大神已经详细讲述了,如下链接     链接:http://h