FZU 2020 Comb(扩展欧几里德求逆元)
2013-05-13 18:50
246 查看
yimao哥的求组合数取余的模板,涨姿势了(¯﹃¯)
/* 组合数的计算; C(n,m)= n*(n-1)*...*(n-m+1) / m!; 注意到本题,m最大为10^4,1s的时限(保守估计是10^7),所以直接计算不超时; 分子: fz: 表示分子:fz= n*(n-1)*...*(n-m+1);最多10^4次乘法, 边乘要边取模; 分母: fm: 表示分母:fm= m*(m-1)*...*2*1;最多10^4次乘法, 边乘要边去模; 最后分母要求对模数p的逆元再与分子相乘; */ #include <cstdio> #include <iostream> using namespace std; int ext_gcd(int a, int b, int &x, int &y){ if( !b ) return x=1,y=0,a; int d= ext_gcd(b, a%b, y, x); y-= a/b*x; return d; } int Inv(int a, int m){ int d,x,y; d= ext_gcd(a,m,x,y); return (x%m+m)%m; } /*计算组合数C(n,m)%p,其中m<=10^4,p是素数,且m<p; fm: 表示分母:fm= m*(m-1)*...*2*1; fz: 表示分子:fz= n*(n-1)*...*(n-m+1); 取余对除法不具有封闭性, 必须求出除数(即分母)对模数p的逆元,转换成乘法; C(n,m)= n*(n-1)*...*(n-m+1) / m!; C(n,m)%p = (fz%p) * Inv( (fm%p), p ) %p; */ long long Comb(int n, int m, int p){ long long fm=1, fz= 1; for(int i=2; i<=m; ++i) fm= fm*i%p; for(int i=n-m+1; i<=n; ++i) fz= fz*i%p; long long ret= fz * Inv( fm, p ) %p; return ret<0 ? ret+p : ret; } int main() { //freopen("E.in","r",stdin); int T,n,m,p; cin>>T; while( T-- ){ cin>>n>>m>>p; cout<< Comb( n, m, p ) <<endl; } }
相关文章推荐
- 扩展欧几里德求逆元模版
- 扩展欧几里德求逆元
- 扩展欧几里德求逆元
- AES基于扩展欧几里德求逆元的S-Box生成
- 除法求逆元(扩展欧几里德和费马小定理)
- POJ-1061青蛙的约会,扩展欧几里德求逆元!
- FZU 2020 组合(扩展欧几里得)
- 乘法逆元: 扩展欧几里德 费马小定理 递推 带余数同余式的一般解法
- CodeForces 146E - Lucky Subsequence DP+扩展欧几里德求逆元
- hdu 3049 Data Processing(扩展欧几里德求逆元)
- Modular Inverse(模逆元,扩展欧几里德)
- 扩展欧几里德,求逆元模板
- 公钥密码之RSA密码算法扩展欧几里德求逆元!!
- FZU - 2020 组合(逆元+卢卡斯)
- 扩展欧几里德求逆元模板
- 【Lucas定理 && C(n, m)%p && 逆元】FZU - 2020 组合
- HDU 5768Lucky7(多校第四场)容斥+中国剩余定理(扩展欧几里德求逆元的)+快速乘法
- 除法求逆元(扩展欧几里德和费马小定理)
- 扩展欧几里德求逆元,快速幂 hdoj 1211
- CodeForces 146E - Lucky Subsequence DP+扩展欧几里德求逆元