大组合数:Lucas定理
2015-09-16 16:29
148 查看
最近碰到一题,问你求
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916155735789-1434010874.png)
mod (p1*p2*p3*……*pl) ,其中n和m数据范围是1~1e18 , l ≤10 , pi ≤ 1e5为不同的质数,并保证M=p1*p2*p3*……*pl ≤ 1e18 。
要解决这个问题首先需要Lucas定理 或者 C!解法。
Lucas定理:
我们令n=sp+q , m=tp+r . q , r ≤ p
那么
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916165615742-537997445.png)
,然后你只要继续对
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916162050445-1418142628.png)
调用Lucas定理即可。
代码可以递归的去完成这个过程,其中递归终点为t = 0 ;
伪代码,时间O(logp(n)*p):
Lucas定理证明:
证明资料:http://www.cut-the-knot.org/arithmetic/algebra/LucasTheorem.shtml
首先你需要这个算式:
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916165322633-1644998653.png)
,然后
(1 + x) nΞ (1 + x) sp+q Ξ ( (1 + x)p)s • (1 + x) q Ξ (1 + xp) s • (1 + x) q (mod p) ;
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916170715648-1158609731.png)
.
所以
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916171148711-1933658153.png)
,通过左右系数比较,你就会发现当i=t , j=r ,(及xtp+r的系数等式)
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916203405929-872322057.png)
成立。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5446
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916155735789-1434010874.png)
mod (p1*p2*p3*……*pl) ,其中n和m数据范围是1~1e18 , l ≤10 , pi ≤ 1e5为不同的质数,并保证M=p1*p2*p3*……*pl ≤ 1e18 。
要解决这个问题首先需要Lucas定理 或者 C!解法。
Lucas定理:
我们令n=sp+q , m=tp+r . q , r ≤ p
那么
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916165615742-537997445.png)
,然后你只要继续对
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916162050445-1418142628.png)
调用Lucas定理即可。
代码可以递归的去完成这个过程,其中递归终点为t = 0 ;
伪代码,时间O(logp(n)*p):
int Lucas (ll n , ll m , int p) { return m == 0 ? 1 : 1ll*comb (n%p , m%p , p) * Lucas (n/p , m/p , p) % p ; } //comb()函数中,因为q , r ≤ p , 所以这部分暴力完成即可。
Lucas定理证明:
证明资料:http://www.cut-the-knot.org/arithmetic/algebra/LucasTheorem.shtml
首先你需要这个算式:
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916165322633-1644998653.png)
,然后
(1 + x) nΞ (1 + x) sp+q Ξ ( (1 + x)p)s • (1 + x) q Ξ (1 + xp) s • (1 + x) q (mod p) ;
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916170715648-1158609731.png)
.
所以
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916171148711-1933658153.png)
,通过左右系数比较,你就会发现当i=t , j=r ,(及xtp+r的系数等式)
![](http://images2015.cnblogs.com/blog/699367/201509/699367-20150916203405929-872322057.png)
成立。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5446
#include<bits/stdc++.h> using namespace std; typedef long long ll ; const int M = 1e5 + 10 ; ll n , m ; int k ; int prime[15] ; int rem[15] ; ll MM ; int F[15] ; //int Finv[15][M] , F[15][M] , inv[15][M] ; ll mul (ll a , ll b , ll mod) { ll tmp = 0 ; while (b) { if (b & 1) tmp = (1ll*tmp+a)%mod ; b >>= 1 ; a = (a+a)%mod ; } return tmp ; } int Fermat (ll a , int b) { int ret = 1 ; int mod = b ; b -= 2 ; while (b) { if (b & 1) ret = mul(ret , a , mod) ; b >>= 1 ; a = mul(a , a , mod) ; } return ret ; } int fact (int n , int p) { int ret = 1 ; for (int i = 1 ; i <= n ; i ++) ret = 1ll*ret*i%p ; return ret ; } int comb (int n , int m , int p) { if (m < 0 || m > n) return 0 ; return 1ll* fact (n , p) * Fermat(fact (m , p) , p) * Fermat (fact(n-m , p) , p) % p ; } int Lucas (ll n , ll m , int p) { return m == 0 ? 1 : 1ll*comb (n%p , m%p , p) * Lucas (n/p , m/p , p) % p ; } void solve () { MM = 1 ; for (int i = 1 ; i <= k ; i ++) { rem[i] = Lucas (n , m , prime[i]) ; MM *= 1ll*prime[i] ; //cout << "rem[i] = " << rem[i] << endl; } ll sum = 0 ; for (int i = 1 ; i <= k ; i ++) { ll tmp = MM/prime[i] ; ll ans = mul (rem[i] , Fermat(tmp , prime[i]) , MM) ; sum = (sum + mul (ans , tmp , MM) ) % MM ; } printf ("%I64d\n" , sum); } int main () { int T ; scanf ("%d" , &T) ; while (T --) { scanf ("%I64d%I64d%d\n" , &n , &m , &k) ; for (int i = 1 ; i <= k ; i ++) { scanf ("%d" , &prime[i]) ; } solve () ; } return 0 ; }
相关文章推荐
- 利用Global 的BeginRequest事件实现域名的重写
- 查询所有sql执行时间
- Redhat6.5安装Docker
- 第三周项目2建设顺序表算法库
- hdu3072 Intelligence System(tarjan缩点+最小树形图)
- docker固定IP地址重启不变
- Dell笔记本不能安装XP或则2003的问题
- 例题6-5 移动盒子 UVa 12657 链表(模拟链表)
- HDU 4746 Mophues(莫比乌斯反演)
- HBase 数据模型
- 常用安全测试用例(一)
- 常用安全测试用例(二)
- 产品交互设计入门书籍推荐(亲自看过)
- VS2008编译问题
- rails 网站跨域
- Android:都是Layout的BaselineAligned惹的祸
- 面试题_List和Set不同
- Delphi星期几的判断
- uva 10253 Series-Parallel Networks 树的性质,可重排列
- POP3、SMTP、IMAP和Exchange都是个什么玩意?