Lucas定理&&hdu3037
来源:互联网 发布:买淘宝号一个多少钱 编辑:程序博客网 时间:2024/06/16 04:10
Lucas定理
Lucas定理主要应用于求C(n,m)%p p是素数(从n取m组合,模上P)。
即:
所以:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)
入门题:
Hdu3037 :
Saving Beans
Problem Description
…….
They want to know that howmany ways there are to save no more than m beans (they are the same) in n trees(different).
The result may be extremelyhuge; you should output the result modulo p
Input
The first line contains one integer T, means the number of cases.
Then followed T lines, each line contains three integers n, m, p, meansthat squirrels will save no more than m same beans in n different trees, 1<= n, m <= 1000000000, 1 < p < 100000 and p is guaranteed to be aprime.
Output
You should output the answermodulo p.
Sample Input
2
1 25
2 15
Sample Output
3
3
Hint
For sample 1, squirrels willput no more than 2 beans in one tree. Since trees are different, we can labelthem as 1, 2 … and so on.
The 3 ways are: put nobeans, put 1 bean in tree 1 and put 2 beans in tree 1. For sample 2, the 3 waysare:
put no beans, put 1 bean in tree 1 and put 1bean in tree 2.
题解:题目意思为求从n个不同的树上 得到不少于m个相同的豆子 ,问有几种解决方案。
首先,先解决排列组合的问题。即,将q个相同的小球,放进p个不同的盒子里(盒子可为空)的总方法数。
因为其盒子可以为空,不便计算,所以假设盒子里已经都有一个球,则球的总数为p+q,且盒子不得为空,那么用插板法,p+q个球中间有p+q-1个空,共要插入p-1个板,则为,C(p-1,p+q-1)。
也可以这么理解:用插板法的话,其共有p-1个板子,将板子与小球混合,再选择p-1个位置,即C(p-1,p+q-1)。
其次,不少于m个,即[0,m]个
所以,方法总数为:
ans=C(n-1,n-1)+ C(n-1,n)+ C(n-1,n+1)+…+ C(n-1,n+m-1)
由排列组合的性质:
C(m,n)=C(m,n-1)+C(m-1,n-1)
( 证明:
对第m个讨论:
若选择了第m个,则在n-1中选m-1即C(n-1,m-1);
若未选择第m个,则在n-1中选m即C(n-1,m) 。 )
原式=C(0,n-1)+ C(1,n)+ C(2,n+1)+…+ C(m,n+m-1)
( C(m,n)= C(n-m,n))
= C(0,n)+ C(1,n)+ C(2,n+1)+…+ C(m,n+m-1)
( C(0,n-1)=C(0,n)= 1)
= C(1,n+1)+ C(2,n+1)+…+ C(m,n+m-1)
(C(m,n)=C(m,n-1)+C(m-1,n-1))
= C(2,n+2)+ C(3,n+2)…+ C(m,n+m-1)
…
= C(m,n+m)
然后,因为题目中要求C(m,n)%p,而C(m,n)若很大,则处理起来会相当麻烦。
所以在此,还要介绍一下Lucas定理:
设p为素数,a,b为正整数,并且
a=akpk+ak-1pk-1+…+a1p+a0
b=bkpk+bk-1pk-1+…+b1p+b0
( 这里0=<ai, bi<=p-1都是整数,i=0,1,2…k.)
则:Cba≡ Cbkak *Cbk-1ak-1*…Cbk0ak0 (mod p)
Lucas定理应用在编程中的就是:
Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)
这就解决了C(m,n)太大求C(m,n)%p不便的问题了!
最后再补充一个小知识——乘法逆元
因为 C(m,n)=n!/( m!*(n-m)!)
由费马小定理(欧拉函数求逆元):
若x是一个不能被质数p整除的整数,则xp-1-1必能被p整除。如果用同余式写法,就是xp-1≡1 mod p。
另一种解释:
( 假如p是质数,且a,p互质,那么a的(p-1)次方除以p的余数恒为1,那么a和a^(p-2)互为乘法逆元,则(b/ a)≡ (b *a^(p-2) ) mod p)
则C(m,n+m)= n! / ( m! * (n-m)!)
= n!* ( m! * (n-m)!)p-2
则C(m,n+m)%p = n!* ( m!* (n-m)!)p-2 %p
这里很明显,用一个快速幂就可以啦!
那么,题目分析到这里就结束了,接着代码就很容易了
#include <iostream>
#include <cstdio>
#include <cstring>
#define LL long long
#define maxn 150000
using namespace std;
LL n,m,p,fac[maxn];
void init()
{
int i;
fac[0]=1;
for(i=1;i<=p;i++)
fac[i]=fac[i-1]*i%p;
}
LL pow(LL a,LL b)
{
LL temp=a%p,ans=1;
while(b)
{
if(b%2) ans=ans*temp%p;
temp=temp*temp%p;
b>>=1;
}
return ans;
}
LL C(LL n,LL m)
{
if(m>n) return 0;
return fac[n]*pow(fac[m]*fac[n-m],p-2)%p;
}
LL Lucas(LL n,LL m)
{
if(m==0) return 1;
else return (C(n%p,m%p)*Lucas(n/p,m/p))%p;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&n,&m,&p);
init();
printf("%lld\n",Lucas(n+m,n));
}
return 0;
}
- 数论 Lucas定理 hdu3037
- HDU3037(Lucas定理)
- hdu3037 LUCAS定理运用。
- Lucas定理&&hdu3037
- lucas定理(hdu3037,)
- 【hdu3037】【Lucas定理】Saving Beans
- hdu3037 lucas 定理 组合数取模
- Hdu3037 Saving Beans Lucas定理
- hdu3037 组合数 lucas定理
- hdu3037 大组合数取模(Lucas定理)
- HDU3037(Lucas定理求大组合数取模)
- 【日常学习】【组合数取模Lucas定理】HDU3037 Saving Beans题解
- hdu3037 Saving Beans (lucas定理+组合数公式)
- [HDU3037]Saving Beans(组合数学Lucas定理)
- hdu3037 隔板法+Lucas定理求大组合取模
- hdu3037 Saving Beans(Lucas定理+费马小定理or扩展欧几里德算发)
- Lucas模板 hdu3037
- Lucas定理简单运用的五题之hdu3037 hdu 3944 fzu 2020 zoj 3557 hdu4349
- 读深入理解Linux内核 (第8章 内存管理, 第一部分 --- 页的管理)
- 表达式语法分析——递归子程序法
- js获取textarea中的值
- ACM新生选拔赛第三场题解
- 点击linearlayout,改变背景颜色
- Lucas定理&&hdu3037
- How to use the function of assembly.
- iOS网页-加载网页(UIWebView)
- 捕捉存储过程错误
- 香蕉派和树霉派上安装ethercat主站IgH
- c++基础之指针
- 函数动态调用 研究
- SQL 数据库 学习 011 关系、一对一、一对多、多对多
- iOS应用安全读书笔记之语音邮件