[模板] Lucas 逆元 快速幂模板
2016-08-06 20:25
330 查看
一般情况下,当Mod较小,组合数较大时用Lucas求组合数,当Mod较大组合数较小时用逆元求组合数
/* 逆元定义:x为a的乘法逆元,(b/a) (mod Mod) = (b * x) (mod Mod) x表示a的逆元。并且 a*x ≡ 1 (mod Mod ) 注意:只有当a与Mod互质的时候才存在逆元 以下两种写法都必须要求MOD为素数 */ typedef long long ll; const int Mod=110119; ll invs[Mod+50]; ll fac[Mod+50]; //1 预处理 void initInv(int Mod){ invs[1]=1; for (int i=2;i<Mod;i++) invs[i]=invs[Mod%i]*(Mod-Mod/i)%Mod; } //2 直接求 ll inv(int a,int mod){ return(a==1?1:inv(mod%a,mod)*(mod-mod/a)%mod); } //3 inv(x)=x^(mod-2) ll qPow(ll x,ll n,ll mod){ ll ret=1; while(n){ if (n&1) ret=(ret*x)%mod; x=(x*x)%mod; n>>=1; } return ret; //x^n%mod } void initFac(int Mod){ //n! fac[0]=1; for(int i=1;i<=Mod;i++){ fac[i]=fac[i-1]*i%Mod; } } ll lucas(ll n,ll k,ll mod){ //C_n^k%mod if (n<0 || k<0 || k>n) return 0; ll ret=1; while(n && k){ ll np=n%mod,kp=k%mod; if (np<kp) return 0; ret=(ret*fac[np]%mod)*invs[fac[kp]*fac[np-kp]%mod]%mod; // ret=(ret*fac[np]%mod)*inv(fac[kp]*fac[np-kp]%mod,mod)%mod; // ret=(ret*fac[np]%mod)*qPow(fac[kp]*fac[np-kp]%mod,mod-2,mod)%mod; n/=mod; k/=mod; } return ret; } //调用 //initFac(Mod); //initInv(Mod); //return lucas(n,m,Mod);
相关文章推荐
- 组合数,快速幂,扩展欧几里得及其求逆元模板
- 模板之快速幂和求逆元
- BZOJ 1951 [Sdoi2010]古代猪文 欧拉定理+(扩展)lucas定理+逆元+快速幂
- HDU 5446——Unknown Treasure——————【CRT+lucas+exgcd+快速乘+递推求逆元】
- HDU 3037 Saving Beans (组合+Lucas定理+逆元+快速幂)
- Lucas模板&快速幂模板
- Smarty模板快速入门
- [Lucas 原理+逆元]BZOJ 4403——序列统计
- 快速幂求余模板
- P3390 【模板】矩阵快速幂
- 矩阵快速幂模板
- HDU 5187 思维+快速幂模板
- HDU 3037 Saving Beans(Lucas定理模板题)
- 洛谷 P1177 【模板】快速排序
- Noip 2013 转圈游戏 - 快速幂模板
- 模板 快速询问GCD
- 【模板】快速幂
- Smarty模板快速入门
- JQuery FlexiGrid的asp.net完美解决方案-dotNetFlexGrid使用指南(二)服务端查询、快速查询和Html模板
- 【快速幂模板】 nyoj102 次方求摸 420 p次方求和(快速幂+同余定理)