lucas定理学习
Lucas定理是用来求 c(n,m) mod p,p为素数的值。
- 表达式:
- C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p
- 当我们遇到求一个N,M很大的组合数的时候,递推法就显得很耗时了,对于1e9那么大的数据求N!%P,无论是空间还是时间都不会允许。
- 于是引申出lucas定理,利用这个表达式可以将数量级降低好几个,从而减小时间和空间的开销。
- 一般来说可以用lucas定理解决的问题都是N,M很大,但质数P相对来说在1e5左右,不会太大,我们利用迭代渐渐缩小N,M的值,
- 将C(N%P,M%P)累乘在答案上求解,下面来思考怎么编写代码。
这个定理目前我不会证明,只是知道内容,惭愧。
当N,M不为0时且组合数合法我们可以继续迭代,当算出来的N%P<M%P时表示结果为0此时直接返回0即可。
对于一个较小的C(n,m)=n!/(m!*(n-m)!) ,我们就可以根据这个式子得到 C(n,m)%P=f(n)%P*(f(m)*f(n-m))-1%P 其中f表示阶乘
由于P是一个质数,由费马小定理可以得到 (f(m)*f(n-m))-1=mod_pow(f(m)*f(n-m),P-2,P),我们可以先打表出f[P]之内的阶乘对P取余然后直接调用即可。
下面是主要代码:
//lucas定理
LL quick_mod(LL a, LL b, LL c)
{
LL ans = ;
while(b)
{
if(b & )
ans = (ans*a)%c;
b>>=;
a = (a*a)%c;
}
return ans;
}
LL fac[MAXN_P];
void Get_Fac(LL p)///m!
{
fac[] = ;
for(int i=; i<=p; i++)
fac[i] = (fac[i-]*i) % p;
}
LL Lucas(LL n, LL m, LL p) //C(n,m)%p
{
LL ans = ;
while(n && m)
{
LL a = n % p;
LL b = m % p;
if(a < b)
return ;
ans = ( (ans*fac[a]%p) * (quick_mod(fac[b]*fac[a-b]%p,p-,p)) ) % p;
n /= p;
m /= p;
}
下面以51nod 1120为例 , 这是题目链接
是一个经典的求卡特兰数的例题,但是N达到了1e9的规模,如果使用O(N)打表,f[n]=(f[n-1]*(4*n-2))/(n+1)得话时间不允许。
还有另一种递推式子是 f[n]=C(N*2,N)/(N+1) ,所以答案就是二倍的第(N-1)个卡特兰数对10007取余,可以用lucas求解,注意有分母的存在要求一下逆元,
由于N很大,也不能用打表法求逆元,可以用拓展欧几里得或者快速幂(由于这里P是质数且lucas就要用到快速幂,所以快速幂很方便不必要重写exgcd)
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 100005
void gcd(LL a,LL b,LL &d,LL &x,LL &y)
{
if(!b) {d=a;x=;y=;}
else {gcd(b,a%b,d,y,x);y-=x*(a/b);}
}
LL Inv(LL a,LL n)
{
LL d,x,y;
gcd(a,n,d,x,y);
return d==?(x+n)%n:-;
} LL quick_mod(LL a, LL b, LL c)
{
LL ans = ;
while(b)
{
if(b & )
ans = (ans*a)%c;
b>>=;
a = (a*a)%c;
}
return ans;
}
LL fac[MAXN];
void Get_Fac(LL p)///m!
{
fac[] = ;
for(int i=; i<=p; i++)
fac[i] = (fac[i-]*i) % p;
}
LL Lucas(LL n, LL m, LL p)
{
LL ans = ;
while(n && m)
{
LL a = n % p;
LL b = m % p;
if(a < b)
return ;
ans = ( (ans*fac[a]%p) * (quick_mod(fac[b]*fac[a-b]%p,p-,p)) ) % p;
n /= p;
m /= p;
}
return ans;
}
int main()
{
LL n, m, p=;
Get_Fac(p);
cin>>n;n--;
cout<<Lucas(n*,n,p)**quick_mod(n+,p-,p)/*Inv(n+1,p)*/%p<<endl;
return ;
}
lucas定理学习的更多相关文章
- lucas 定理学习
大致意思就是求组合数C(n , m) % p的值, p为一个偶数 可以将组合数的n 和 m都理解为 p 进制的表示 n = ak*p^k + a(k-1)*p^(k-1) + ... + a1*p ...
- Lucas定理学习小记
(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 = [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...
- Lucas定理学习(进阶中)
(1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 = [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...
- Lucas定理学习笔记
从这里开始 一个有趣的问题 扩展Lucas算法 一个有趣的问题 题目大意 给定$n, m, p$,求$C_{n}^{m}$除以$p$后的余数. Subtask#1 $0\leqslant m\leq ...
- Lucas定理学习笔记(没有ex_lucas)
题目链接\(Click\) \(Here\) \(ex\_lucas\)实在是不能学的东西...简单学了一下\(Lucas\)然后打算就这样鸽着了\(QwQ\)(奶一口不可能考) 没什么复杂的,证明的 ...
- [Lucas定理]【学习笔记】
Lucas定理 [原文]2017-02-14 [update]2017-03-28 Lucas定理 计算组合数取模,适用于n很大p较小的时候,可以将计算简化到小于p $ \binom{n}{m} \m ...
- [学习笔记]扩展LUCAS定理
可以先做这个题[SDOI2010]古代猪文 此算法和LUCAS定理没有半毛钱关系. [模板]扩展卢卡斯 不保证P是质数. $C_n^m=\frac{n!}{m!(n-m)!}$ 麻烦的是分母. 如果互 ...
- 【转】Lucas定理 & 逆元学习小结
(From:离殇灬孤狼) 这个Lucas定理是解决组合数的时候用的,当然是比较大的组合数了.比如C(1000000,50000)% mod,这个mod肯定是要取的,要不算出来真的是天文数字了. 对于一 ...
- lucas定理 +证明 学习笔记
lucas定理 p为素数 \[\dbinom n m\equiv\dbinom {n\%p} {m\%p} \dbinom {n/p}{m/p}(mod p)\] 左边一项直接求,右边可递归处理,不包 ...
随机推荐
- 使用jqueryUI和corethink实现的类似百度的搜索提示
代码:http://download.csdn.net/detail/u012995856/9676845 效果: 目录: 这里是以corethink模块的形式,只需要安装上访问 index.php? ...
- (转)牛B的代码不一定是好代码
最近经常做业务逻辑代码review的工作,发现各种风格的代码,其中有一种是封装和抽象做的非常的多,代码层次非常的深入,表面给人感觉是:牛逼的代码. 但是从清晰度和可维护性来说,还是不推荐这么做. 1. ...
- Selenium WebDriver 2.34.0 发布,支持Firefox22
Selenium WebDriver 2.34.0 发布,支持Firefox22http://automationqa.com/forum.php?mod=viewthread&tid=270 ...
- sql 转
- Linux curl命令参数详解(6/23)
linux curl是通过url语法在命令行下上传或下载文件的工具软件,它支持http,https,ftp,ftps,telnet等多种协议,常被用来抓取网页和监控Web服务器状态. 在Linux中c ...
- bug最后汇总-2018/08/03
一.对于点击后请求时间过长的按钮 现象:容易给用户点击无效的错觉,从而导致多次点击,从而发出多个相同请求,这显然是不符合我们意愿的 解决: 用户点击发出多个请求:加个锁,当用户点击后,将锁关闭,使用户 ...
- Python面试题之Super函数
这是个高大上的函数,在python装13手册里面介绍过多使用可显得自己是高手 23333. 但其实他还是很重要的. 简单说, super函数是调用下一个父类(超类)并返回该父类实例的方法. 这里的下一 ...
- 【WIN7】windows\system32 下的几乎所有文件的简单说明【1】
1: aclui.dll .....Security Descriptor Editor,没有它,注册表编缉器会无法运行 2: ACTIVEDS.DLL .....(ADs 路由层 DLL). 没有它 ...
- mysql配置文件生效顺序
安装完数据库 除了将my.cnf放在/etc/下放在其他地方也是可以的 cp /usr/share/mysql/my-default.cnf /etc/my.cnf 今天就看一下这些my.cnf是怎么 ...
- SpringBoot MockMVC
使用MockMvc,我们可以完成基于RESTful风格的SpringMVC的测试,我们可以测试完整的Spring MVC流程,即从URL请求到控制器处理,再到视图渲染都可以测试. @RunWith(S ...