FZU 2020 组合 lucas
2016-04-06 23:17
375 查看
组合数取模的模板题
https://en.wikipedia.org/wiki/Lucas%27_theorem
这里有lucas的证明
说一下我对lucas的一点理解
lucas定理就是将C(m,n)分解为C(m1,n1)* C(m2,n2)* C(m3,n3)…….C(mk,nk)
其中m1+m2p+m3p^2+m3p^4+…..mkp^k=m
n1+n2p+n3p^2+n3p^4+…..nkp^k=n
很明显每个数都能化成以上形式
m1=m%p m2=m/p%p m3=m/(p^2)%p以此类推进行递归
上边就是lucas这个函数了
解释一下怎么求C(m,n)
因为
就像上式一样,通过枚举1~n就行了
ans*=(m-n+i)/i
因为我们要mod p 所以不能进行除法
所以ans*=(m-n+i) * inv(i)
inv(i)是i对模mod的逆元
逆元就是x*y=1(mod p) y就是x对p的逆元
逆元的求法可以通过费马小定理
因为p是素数,所以可以引用费马小定理
a^(p-1)=a*a^(p-2)=1 (mod p)
所以a^(p-2)就是a对p的逆元,通过快速幂求解就ok了
有时候时间不允许我们枚举n,所以可以通过预处理m!和inv(n!)来省掉枚举n
(如果有什么错误的地方,请菊苣指出orz
https://en.wikipedia.org/wiki/Lucas%27_theorem
这里有lucas的证明
说一下我对lucas的一点理解
lucas定理就是将C(m,n)分解为C(m1,n1)* C(m2,n2)* C(m3,n3)…….C(mk,nk)
其中m1+m2p+m3p^2+m3p^4+…..mkp^k=m
n1+n2p+n3p^2+n3p^4+…..nkp^k=n
很明显每个数都能化成以上形式
m1=m%p m2=m/p%p m3=m/(p^2)%p以此类推进行递归
上边就是lucas这个函数了
解释一下怎么求C(m,n)
因为
就像上式一样,通过枚举1~n就行了
ans*=(m-n+i)/i
因为我们要mod p 所以不能进行除法
所以ans*=(m-n+i) * inv(i)
inv(i)是i对模mod的逆元
逆元就是x*y=1(mod p) y就是x对p的逆元
逆元的求法可以通过费马小定理
因为p是素数,所以可以引用费马小定理
a^(p-1)=a*a^(p-2)=1 (mod p)
所以a^(p-2)就是a对p的逆元,通过快速幂求解就ok了
有时候时间不允许我们枚举n,所以可以通过预处理m!和inv(n!)来省掉枚举n
(如果有什么错误的地方,请菊苣指出orz
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #include<queue> #include<stack> #include<string> #include<vector> #include<map> #include<set> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) typedef long long LL; #define maxn 10005 const int inf=(1<<28)-1; LL p; LL quick_mod(LL a, LL b) { LL ans = 1; a %= p; while(b) { if(b & 1) { ans = ans * a % p; b--; } b >>= 1; a = a * a % p; } return ans; } LL C(LL n, LL m) { if(m > n) return 0; LL ans = 1; for(int i=1; i<=m; i++) { LL a = (n + i - m) % p; LL b = i % p; ans = ans * (a * quick_mod(b, p-2) % p) % p; } return ans; } LL Lucas(LL n, LL m) { if(m == 0) return 1; return C(n % p, m % p) * Lucas(n / p, m / p) % p; } int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d%lld",&m,&n,&p); printf("%d\n",Lucas(m,n)); } return 0; }
相关文章推荐
- 变态组合数C(n,m)求解
- 关于Fibonacci算法及Lucas算法说明
- 蓝桥练习系统 历届试题 公式求值
- HDU 4349(Lucas 变形)
- lightOJ 1067 - Combinations
- Bzoj1951 [Sdoi2010]古代猪文
- 组合(Lucas)
- 1951: [Sdoi2010]古代猪文
- BZOJ 4403: 序列统计|Lucas定理
- 【BZOJ3656】异或【扩展Lucas】【线性无关】
- fzu 2020 Lucas 定理,组合数求模模板
- 数论--Lucas Theorem
- HDU - 6129 Just do it(找规律)
- 2017百度之星初赛(B) 1001 Chess(思维+Lucas)
- Lucas定理(大数组合数取模)
- 2016 Multi-University Training Contest 6 解题报告
- hdu5894hannnnah_j’s Biological Test+组合数学+Lucas
- 【BZOJ 4403】【推公式+Lucas定理】 序列统计
- 【hdu 5894】【组合数学 lucas 费马小求逆元】 【m个人坐n个围成一周的位置每个人距离至少为k,求方法数】
- 找规律+Lucas定律_______A Simple Chess(hdu 5794 2016多校第六场)