[转]组合数取模 Lucas定理
2015-06-19 13:04
507 查看
对于C(n, m) mod p。这里的n,m,p(p为素数)都很大的情况。就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了。
这里用到Lusac定理
For non-negative integers m and n and a prime p, the following congruence relation holds:
![](http://upload.wikimedia.org/math/8/0/f/80f5b11e04357a7d3de679e741079a2a.png)
where
![](http://upload.wikimedia.org/math/e/4/7/e47bc5720a472962ece8dfa78e12320c.png)
and
![](http://upload.wikimedia.org/math/5/5/b/55ba93b4d2fbd7950e0c356f04f372cc.png)
are the base p expansions of m and n respectively.
对于单独的C(ni, mi) mod p,已知C(n, m) mod p = n!/(m!(n - m)!) mod p。显然除法取模,这里要用到m!(n-m)!的逆元。
根据费马小定理:
已知(a, p) = 1,则 ap-1 ≡ 1 (mod p), 所以 a*ap-2 ≡ 1 (mod p)。
也就是 (m!(n-m)!)的逆元为 (m!(n-m)!)p-2 ;
代码:
#include <iostream>
using namespace std;
typedef long long LL;
这里用到Lusac定理
For non-negative integers m and n and a prime p, the following congruence relation holds:
![](http://upload.wikimedia.org/math/8/0/f/80f5b11e04357a7d3de679e741079a2a.png)
where
![](http://upload.wikimedia.org/math/e/4/7/e47bc5720a472962ece8dfa78e12320c.png)
and
![](http://upload.wikimedia.org/math/5/5/b/55ba93b4d2fbd7950e0c356f04f372cc.png)
are the base p expansions of m and n respectively.
对于单独的C(ni, mi) mod p,已知C(n, m) mod p = n!/(m!(n - m)!) mod p。显然除法取模,这里要用到m!(n-m)!的逆元。
根据费马小定理:
已知(a, p) = 1,则 ap-1 ≡ 1 (mod p), 所以 a*ap-2 ≡ 1 (mod p)。
也就是 (m!(n-m)!)的逆元为 (m!(n-m)!)p-2 ;
代码:
#include <iostream>
using namespace std;
typedef long long LL;
LL exp_mod(LL a, LL b, LL p) { LL res = 1; while(b != 0) { if(b&1) res = (res * a) % p; a = (a*a) % p; b >>= 1; } return res; } LL Comb(LL a, LL b, LL p) { if(a < b) return 0; if(a == b) return 1; if(b > a - b) b = a - b; LL ans = 1, ca = 1, cb = 1; for(LL i = 0; i < b; ++i) { ca = (ca * (a - i))%p; cb = (cb * (b - i))%p; } ans = (ca*exp_mod(cb, p - 2, p)) % p; return ans; } LL Lucas(int n, int m, int p) { LL ans = 1; while(n&&m&&ans) { ans = (ans*Comb(n%p, m%p, p)) % p; n /= p; m /= p; } return ans; } int main() { Read(); int n, m, p; while(~scanf("%d%d%d", &n, &m, &p)) { printf("%lld\n", Lucas(n, m, p)); } return 0; }
相关文章推荐
- 2015年11月软考中级、高级学员重点班开讲了!
- 黑马day05 Cookie小案例&记录上次访问的图书
- Spring Profile 使用
- Android版本和API Level对应关系
- BZOJ3325 : [Scoi2013]密码
- 炒股第一招【看盘技巧】
- 北大OJ_1004题:Financial Management
- SQLYog快捷键大全
- CImage load内存泄露
- UIMenuController使用
- UVA 489 Hangman Judge (字符匹配)
- 实现沉浸式状态栏
- 炒股第二招【买卖技巧】
- mx player ac3音频不能播放,mx player解码器,播放MKV格式视频
- 10个利用Eclipse调试Java的常见技巧
- Vmware 的三种网络连接方式
- SQL的inner join、left join、right join、full outer join、union、union all的区别
- android 三种定位方式
- 我的Android Studio习惯
- JavaScript 闭包