卢卡斯定理 Lucas (p为素数)

证明摘自:(我网上唯一看得懂的证明)

https://blog.csdn.net/alan_cty/article/details/54318369

结论:(显然递归实现)
lucas(n,m)=lucas(n/p,m/p)*C(n%p,m%p)
将n,m很大的数压成求两个小于p的组合数的乘积

数学上的卢卡斯定理两种形式:(n,m用p进制表示)

上代码:

//打表
void init(ll x){
rec[0]=1;
For(i,1,x)mulmod(rec[i],rec[0]*i);
}
//逆元
ll inv(ll x){
return qmul(x,mod-2);
}
//求组合数
ll C(ll n,m){
if(n<m)return 0;
return rec[n]*inv[rec[m]%mod*inv[n-m]%mod;
}
//卢卡斯
ll lucas(ll n,m){
if(n<m)return 0;
ll ans=1;
for(;m;n/=mod,m/=mod)
mulmod(ans,C(n%mod,m%mod));
return ans;
}

原文地址:https://www.cnblogs.com/planche/p/9397495.html

时间: 2024-11-08 20:56:00

卢卡斯定理 Lucas (p为素数)的相关文章

洛谷.3807.[模板]卢卡斯定理(Lucas)

题目链接 Lucas定理 日常水题...sublime和C++字体死活不同步怎么办... //想错int范围了...不要被longlong坑 //这个范围现算阶乘比预处理快得多 #include <cstdio> typedef long long LL; const int N=1e5+5; LL n,m,p;//,fac[N+3]; LL FP(LL x,LL k,LL p) { LL t=1; for(; k; k>>=1,x=x*x%p) if(k&1) t=t*x

数论篇7——组合数 &amp; 卢卡斯定理(Lucas)

组合数 组合数就是高中排列组合的知识,求解组合数C(n,m),即从n个相同物品中取出m个的方案数. 求解方式 求解通式:$C^{m}_{n}=\dfrac {n!}{m!\left( n-m\right) !}$ 性质1:$C^{m}_{n}=C_{n}^{n-m}$ 性质2:$C^{m}_{n}=C^{m-1}_{n-1}-i+C^{m}_{n-1}$ 打表递推 根据性质2:$C^{m}_{n}=C^{m-1}_{n-1}+C^{m}_{n-1}$ 组合数算出来特别大,往往都会要求取余,这里取

卢卡斯定理的模板以及应用

定义: Lucas定理是用来求 C(n,m) MOD p,p为素数的值.Lucas定理:我们令n=sp+q,m=tp+r.(q,r≤p) 那么:(在编程时你只要继续对 调用 Lucas 定理即可.代码可以递归的去完成这个过程,其中递归终点为 t=0 :时间复杂度 O(logp(n)?p):) 主要解决当 n,m 比较大的时候,而 p 比较小的时候 <1e6 ,那么我们就可以借助 卢卡斯定理来解决这个问题: 模板: #include <iostream> #include <cstd

卢卡斯定理

卢卡斯定理:解决一类组合数取模问题 A.B是非负整数,p是质数.AB写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]. 则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0])  modp同余 即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p) 这个是单独处理n!的情况,当然C(n,m)就是n!/(m!*(n-m)!),每一个阶乘都用上面的方法处理的话,就是Luc

【BZOJ 1272】 1272: [BeiJingWc2008]Gate Of Babylon (容斥原理+卢卡斯定理)

1272: [BeiJingWc2008]Gate Of Babylon Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 254  Solved: 120 Description Input Output Sample Input Sample Output 12 HINT Source [分析] T很小,跟以前的某一题很像啊,就是容斥. 枚举不符合的(超过限制的),2^t,然后就是算 n种无限多的东东中选m个. 经典的组合数题,$C_{n+m-1

洛谷 P3807 【模板】卢卡斯定理

题目背景 这是一道模板题. 题目描述 给定n,m,p(1\le n,m,p\le 10^51≤n,m,p≤105) 求 C_{n+m}^{m}\ mod\ pCn+mm? mod p 保证P为prime C表示组合数. 一个测试点内包含多组数据. 输入输出格式 输入格式: 第一行一个整数T(T\le 10T≤10),表示数据组数 第二行开始共T行,每行三个数n m p,意义如上 输出格式: 共T行,每行一个整数表示答案. 输入输出样例 输入样例#1: 复制 2 1 2 5 2 1 5 输出样例#

[Sdoi2010]古代猪文 (卢卡斯定理,欧拉函数)

哇,这道题真的好好,让我这个菜鸡充分体会到卢卡斯和欧拉函数的强大! 先把题意抽象出来!就是计算这个东西. p=999911659是素数,p-1=2*3*4679*35617 所以:这样只要求出然后再快速乘法就行了. 那好,怎么做呢? 有模运算的性质得到  然后就是卢卡斯原理. 先把卢卡斯原理放这里: void init(int mod){ //对mod取余后,一定小于mod,因此把mod的阶乘存起来就够用 f[0] = 1; for (int i = 1; i <= mod; i++){ f[i

ACM-ICPC 2015 Changchun Preliminary Contest J. Unknown Treasure (卢卡斯定理+中国剩余定理)

题目链接:https://nanti.jisuanke.com/t/A1842 题目大意:给定整数n,m,k,其中1≤m≤n≤1018,k≤10, 然后给出k个素数,保证M=p[1]*p[2]……*p[k]≤1018,p[i]≤105 求C(n,m)%(p[1]*p[2]……*p[k]) 解题思路:因为模数太大,所以我们先用卢卡斯定理求出对每个素数的模,然后再通过中国剩余定理就可以求得对它们的乘积的模. 代码: #include<bits/stdc++.h> using namespace s

cf451E Devu and Flowers 卢卡斯定理+容斥定理

题目:http://codeforces.com/problemset/problem/451/E 题意:有n个盒子(n<=20),每个盒子中有10^12个小球,现从每个盒子中取出若干球(可为0),求共取出s个小球(s<=10^14)的方案数. 组合数学问题,求C(n,m).但n,m过大时,可用卢卡斯定理. 卢卡斯定理:C(n,m) %p = C(n/p,m/p) * C(n%p,m%p) 从n个盒子中取出s个球的方案数,相当于插板,即 C(s+n-1,n-1).注意这是没有限制条件的情况.