卢卡斯定理(lucas)

[用途]

求解 C n m % p C_{n}^{m}\% p Cnm​%p,其中m,n较大,p较小且为素数

[结论]

C n m ≡ C n / p m / p C n % p m % p ( m o d p ) C_{n}^{m}\equiv C_{n/p}^{m/p}C_{n\%p}^{m\%p}(mod \quad p) Cnm​≡Cn/pm/p​Cn%pm%p​(modp)

[证明]

假设: { n = s p + q m = t p + r \left\{\begin{array}{cc} n=sp+q\\ m=tp+r \end{array}\right. {n=sp+qm=tp+r​
即证明 C n m ≡ C s t C q r ( m o d p ) C_{n}^{m}\equiv C_{s}^{t}C_{q}^{r}(mod \quad p) Cnm​≡Cst​Cqr​(modp)
使用构造法:
( 1 + x ) n ≡ ( 1 + x ) s p + q ≡ [ ( 1 + x ) p ] s ( 1 + x ) q ( m o d p ) (1+x)^{n}\equiv(1+x)^{sp+q}\equiv[(1+x)^{p}]^{s}(1+x)^{q}(mod \quad p) (1+x)n≡(1+x)sp+q≡[(1+x)p]s(1+x)q(modp)
根据二项式定理
( 1 + x ) p = ∑ i = 0 p C p i x i (1+x)^{p}=\sum\limits_{i=0}^p{C_{p}^{i}x^{i}} (1+x)p=i=0∑p​Cpi​xi
除了第一项 C p 0 x 0 ( 即 1 ) C_{p}^{0}x^{0}(即1) Cp0​x0(即1)与最后一项 C p p x p ( 即 x p ) C_{p}^{p}x^{p}(即x^{p}) Cpp​xp(即xp)不能整除p,中间项均能整除p,所以在 ( m o d p ) (mod \quad p) (modp)意义下 ( 1 + x ) p = 1 + x p (1+x)^{p}=1+x^{p} (1+x)p=1+xp
则 ( 1 + x ) n ≡ [ ( 1 + x ) p ] s ( 1 + x ) q ≡ ( 1 + x p ) s ( 1 + x ) q ( m o d p ) (1+x)^{n}\equiv[(1+x)^{p}]^{s}(1+x)^{q}\equiv(1+x^{p})^{s}(1+x)^{q}(mod \quad p) (1+x)n≡[(1+x)p]s(1+x)q≡(1+xp)s(1+x)q(modp)
即 ∑ k = 0 n C n k x k ≡ ∑ i = 0 s C s i x p i ∑ j = 0 q C q j x j ( m o d p ) \sum\limits_{k=0}^n{C_{n}^{k}x^{k}}\equiv\sum\limits_{i=0}^s{C_{s}^{i}x^{pi}}\sum\limits_{j=0}^q{C_{q}^{j}x^{j}}(mod \quad p) k=0∑n​Cnk​xk≡i=0∑s​Csi​xpij=0∑q​Cqj​xj(modp)
我们在等式两边找 x m x^m xm项的系数
左:含 x m x^m xm项显然是 C n m C_{n}^{m} Cnm​
右:含 x m x^m xm项只能由 x p i x j = x p i + j x^{pi}x^{j}=x^{pi+j} xpixj=xpi+j得到,即 m = p i + j m=pi+j m=pi+j,显然 i = t , j = r i=t,j=r i=t,j=r,此时对应系数恰好是 C s t C q r C_{s}^{t}C_{q}^{r} Cst​Cqr​
所以 C n m ≡ C s t C q r ( m o d p ) C_{n}^{m}\equiv C_{s}^{t}C_{q}^{r}(mod \quad p) Cnm​≡Cst​Cqr​(modp)成立
即 C n m ≡ C n / p m / p C n % p m % p ( m o d p ) C_{n}^{m}\equiv C_{n/p}^{m/p}C_{n\%p}^{m\%p}(mod \quad p) Cnm​≡Cn/pm/p​Cn%pm%p​(modp)

[代码]

#include<iostream>
using namespace std;
typedef long long LL;
const LL N=1e5+2;
LL a[N];
void init(LL p)
{a[1]=1;for(int i=2;i<=p;++i)a[i]=a[i-1]*i%p;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{if(!b){x=1;y=0;return;}exgcd(b,a%b,y,x);y-=a/b*x;
}
LL ksm(LL x,LL n,LL mod)
{LL ans=1;while(n){if(n&1)ans=ans*x%mod;n>>=1;x=x*x%mod;}return ans;
}
LL C(LL n,LL m,LL p)
{if(n==m||m==0)return 1;if(n<m)return 0;if(m*2>n)m=n-m;                        /*C(n,m)=c(n,n-m)*/return a[n]*ksm(a[m]*a[n-m],p-2,p)%p; /*求(a[m]*a[n-m])在(mod p)意义下的乘法逆元*//*拓展欧几里得与费马小定理均可*/ /*LL x,y;exgcd(a[m]*a[n-m],p,x,y);return (a[n]*x%p+p)%p;*/
}
LL lucas(LL n,LL m,LL p)
{if(!m)return 1;return lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
int main()
{ios::sync_with_stdio(false);LL T,n,m,p;cin>>T;while(T--){cin>>n>>m>>p;init(p);cout<<lucas(n+m,m,p)<<endl;}return 0;
}

拓展卢卡斯定理(exlucas)

[用途]

求解 C n m % P C_{n}^{m}\% P Cnm​%P,其中m,n较大,P较小且不一定为素数

[解析]

转化为中国剩余定理(crt)

根据算术基本定理

P = M 1 M 2 . . . M k = ∏ i = 0 k M i P=M_{1}M_{2}...M_{k}=\prod\limits_{i=0}^{k}M_{i} P=M1​M2​...Mk​=i=0∏k​Mi​
其中 M i = p i t i , M i M j ( i ! = j ) M_{i}=p_{i}^{t_{i}},M_{i}M_{j}(i!=j) Mi​=piti​​,Mi​Mj​(i!=j)两两互素
设 X = C n m X=C_{n}^{m} X=Cnm​
则 A i = C n m % M i A_{i}=C_{n}^{m}\%M_{i} Ai​=Cnm​%Mi​
所以转化为中国剩余定理
X ≡ { A 1 ( m o d M 1 ) A 2 ( m o d M 2 ) . . . A k ( m o d M k ) X\ \equiv\left\{\begin{array}{cc} A_{1} \quad (mod \quad M_{1})\\ A_{2} \quad (mod \quad M_{2})\\ ...\\ A_{k} \quad (mod \quad M_{k}) \end{array}\right. X ≡⎩⎪⎪⎨⎪⎪⎧​A1​(modM1​)A2​(modM2​)...Ak​(modMk​)​
M i M_{i} Mi​根据算术基本定理循环分解即可
重点的是 A i A_{i} Ai​
A i = C n m % M i = n ! m ! ( n − m ) ! % M i \begin{aligned}A_{i} &amp;=C_{n}^{m}\%M_{i}\\ &amp;=\frac{n!}{m!(n-m)!}\%M_{i}\\ \end{aligned} Ai​​=Cnm​%Mi​=m!(n−m)!n!​%Mi​​
可惜的是 m ! ( n − m ) ! 在 模 M i ( M i = p i t i ) m!(n-m)!在模M_{i}(M_i=p_{i}^{t_{i}}) m!(n−m)!在模Mi​(Mi​=piti​​)意义下的乘法逆元不一定存在
我们可以先把阶层中含 p i p_{i} pi​的项约去,这样就可以求逆元了,然后再乘回来即可
所以
A i = n ! m ! ( n − m ) ! % M i = n ! p i m ! p i ( n − m ) ! p i p i k % M i = n ! p i i n v ( m ! p i , M i ) i n v ( ( n − m ) ! p i , M i ) p i k % M i = ( n ! p i % M i ) i n v ( m ! p i % M i , M i ) i n v ( ( n − m ) ! p i % M i , M i ) p i k % M i \begin{aligned}A_{i} &amp;=\frac{n!}{m!(n-m)!}\%M_{i}\\ &amp;=\frac{\frac{n!}{p_i}}{\frac{m!}{p_i}\frac{(n-m)!}{p_i}}p_i^k\%M_{i}\\ &amp;=\frac{n!}{p_i}inv(\frac{m!}{p_i},M_i)inv(\frac{(n-m)!}{p_i},M_i)p_i^k\%M_{i}\\ &amp;=(\frac{n!}{p_i}\%M_{i})inv(\frac{m!}{p_i}\%M_{i},M_i)inv(\frac{(n-m)!}{p_i}\%M_{i},M_i)p_i^k\%M_{i} \end{aligned} Ai​​=m!(n−m)!n!​%Mi​=pi​m!​pi​(n−m)!​pi​n!​​pik​%Mi​=pi​n!​inv(pi​m!​,Mi​)inv(pi​(n−m)!​,Mi​)pik​%Mi​=(pi​n!​%Mi​)inv(pi​m!​%Mi​,Mi​)inv(pi​(n−m)!​%Mi​,Mi​)pik​%Mi​​


n n = n ! p i % M i nn=\frac{n!}{p_i}\%M_{i} nn=pi​n!​%Mi​
m m = m ! p i % M i mm=\frac{m!}{p_i}\%M_{i} mm=pi​m!​%Mi​
n m = ( n − m ) ! p i % M i nm=\frac{(n-m)!}{p_i}\%M_{i} nm=pi​(n−m)!​%Mi​
则 A i = n n ∗ i n v ( m m , M i ) ∗ i n v ( n m , M i ) ∗ p i k % M i A_i=nn*inv(mm,M_i)*inv(nm,M_i)*p_i^k\%M_i Ai​=nn∗inv(mm,Mi​)∗inv(nm,Mi​)∗pik​%Mi​
现在的关键又转换为求 n n , m m , n m nn,mm,nm nn,mm,nm了
就nn来看
当n=19时, p i = 3 , t i = 2 p_i=3,t_i=2 pi​=3,ti​=2
n ! = 1 ∗ . . . ∗ 19 = 3 6 ∗ 6 ! ∗ [ ( 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 ) ∗ ( 10 ∗ 11 ∗ 13 ∗ 14 ∗ 16 ∗ 17 ) ∗ 19 ) ] n!=1*...*19=3^6*6!*[(1*2*4*5*7*8)*(10*11*13*14*16*17)*19)] n!=1∗...∗19=36∗6!∗[(1∗2∗4∗5∗7∗8)∗(10∗11∗13∗14∗16∗17)∗19)]
n ! p i % M i = [ ( 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 ) ∗ ( 10 ∗ 11 ∗ 13 ∗ 14 ∗ 16 ∗ 17 ) ∗ 19 ) ] ∗ 6 ! % M i \frac{n!}{p_i}\%M_{i}=[(1*2*4*5*7*8)*(10*11*13*14*16*17)*19)]*6!\%M_i pi​n!​%Mi​=[(1∗2∗4∗5∗7∗8)∗(10∗11∗13∗14∗16∗17)∗19)]∗6!%Mi​
而中括号这一堆是有循环节的 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 ≡ 10 ∗ 11 ∗ 13 ∗ 14 ∗ 16 ∗ 17 ( m o d M i ) 1*2*4*5*7*8\equiv10*11*13*14*16*17(mod\quad M_i) 1∗2∗4∗5∗7∗8≡10∗11∗13∗14∗16∗17(modMi​)
循环节为 n / M i n/M_i n/Mi​,循环一组后然后快速幂就行了
剩下的个数就是 n % M i n\%M_i n%Mi​这一类直接循环相乘
而 6 ! 6! 6!恰好是 ( n / p i ) ! (n/p_i)! (n/pi​)!,直接递归即可
即 n ! p i % M i = [ . . . ] ∗ ( n / p i ) ! p i % M i \frac{n!}{p_i}\%M_{i}=[...]*\frac{(n/p_i)!}{p_i}\%M_{i} pi​n!​%Mi​=[...]∗pi​(n/pi​)!​%Mi​
[ . . . ] [...] [...]就是上面的循环节那块,分类进行求解,over!

[代码]

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N=1e5+9;
LL A[N],M[N];
LL ksm(LL x,LL n,LL mod)
{LL ans=1;while(n){if(n&1)ans=ans*x%mod;n>>=1,x=x*x%mod;}return ans;
}
void exgcd(LL a,LL b,LL &x,LL &y)
{if(!b)x=1,y=0;else exgcd(b,a%b,y,x),y-=a/b*x;
}
LL inv(LL a,LL p)
{LL x,y;exgcd(a,p,x,y);return (x+p)%p?x:x+p;
}
LL get(LL n,LL pi,LL p)                                 /*求(与pi互素后的n!)%M[i]*/
{if(!n)return 1;LL ans=1;if(n/p){                                          /*判断有无循环节 */ for(LL i=2;i<=p;++i)if(i%pi)ans=ans*i%p;ans=ksm(ans,n/p,p);}for(LL i=2;i<=n%p;++i)if(i%pi)ans=ans*i%p;            /*循环节剩余部分*/ return ans*get(n/pi,pi,p)%p;
}
LL exlucas(LL n,LL m,LL pi,LL p)                        /*求A[i]*/
{LL nn=get(n,pi,p);                                    /*求(与pi互素后的n)%M[i]*/ LL mm=get(m,pi,p);                                    /*求(m!与pi互素后的m!)%M[i]*/ LL nm=get(n-m,pi,p);                               /*求(与pi互素后的(n-m)!)%M[i]*/ LL k=0;                                              /*含质因数pi的数量*/ for(LL i=n;i;i/=pi)k+=i/pi;for(LL i=m;i;i/=pi)k-=i/pi;for(LL i=n-m;i;i/=pi)k-=i/pi;return nn*inv(mm,p)*inv(nm,p)*ksm(pi,k,p)%p;
}
LL crt(LL len,LL Lcm)
{LL ans=0;for(LL i=1;i<=len;++i){LL Mi=Lcm/M[i];ans=((ans+A[i]*inv(Mi,M[i])*Mi)%Lcm+Lcm)%Lcm;}return ans;
}
int main()
{ios::sync_with_stdio(false);LL n,m,P,num;while(cin>>n>>m>>P){if(n<m){cout<<0<<endl;continue;}num=0;memset(A,0,sizeof(A));memset(M,0,sizeof(M));for(LL x=P,i=2;i<=P;++i)if(x%i==0){M[++num]=1;while(x%i==0){M[num]*=i;x/=i;}A[num]=exlucas(n,m,i,M[num])%P;} cout<<crt(num,P)<<endl;}return 0;
}

数论-卢卡斯定理(lucas)与拓展卢卡斯定理 (exlucas)相关推荐

  1. 【luogu P3807】【模板】卢卡斯定理/Lucas 定理(含 Lucas 定理证明)

    [模板]卢卡斯定理/Lucas 定理 题目链接:luogu P3807 题目大意 求 C(n,n+m)%p 的值. p 保证是质数. 思路 Lucas 定理内容 对于非负整数 nnn,mmm,质数 p ...

  2. 牛客练习赛22 E 树状数组 + DFS + 拓展欧几里德定理

    题目链接 题意: 给定一个长度为nnn的序列,进行mmm次操作,操作有两类: 111 LLL RRR vvv : 区间[L,R][L, R][L,R]的每个数加上vvv 222 LLL RRR ppp ...

  3. 欧几里德与拓展欧几里德定理

    一.欧几里德定理 欧几里德定理就是辗转相除法的原理,用来求两个整数的最大公约数gcd(a, b). 推理过程: 辗转相除法是由辗转相减法而来的,如果a和b(假设a>b)的最大公约数是k,那么可以 ...

  4. 初等数论四大定理之——费马小定理

    皮埃尔·德·费马(Pierre de Fermat),1601年生于法国,是一个律师和业余数学家.他在数学多个分支上都有贡献,成就甚至超过了许多职业的数学家,被誉为"业余数学家之王" ...

  5. 初等数论四大定理(威尔逊定理,欧拉定理,中国剩余定理,费马小定理)

    1.威尔逊定理:在初等数论中,威尔逊定理给出了判定一个自然数是否为素数的充分必要条件.即:当且仅当p为素数时:( p -1 )! ≡ p-1 ( mod p ),但是由于阶乘是呈爆炸增长的,其结论对于 ...

  6. donsker定理_中心极限定理和Donsker定理

    为什么要关心中心极限定理和Donsker定理 这可能就是Donsker定理要解决的问题.与Donsker定理相关的,还有Glivenko-Cantelli Theorem,似乎与中心极限定理与大数定律 ...

  7. 【组合数学】组合存在性定理 ( 三个组合存在性定理 | 有限偏序集分解定理 | Ramsey 定理 | 相异代表系存在定理 | Ramsey 定理内容概要 )

    文章目录 一.组合存在性定理 二.Ramsey 定理内容概要 一.组合存在性定理 组合存在性定理 主要有三个定理 , 有限偏序集分解定理 , Ramsey 定理 , 相异代表系存在定理 ; 1. 有限 ...

  8. (组合数学笔记)Pólya计数理论_Part.9_Pólya定理的推广——De Bruijn定理

    文章目录 写在前面 问题引入 推导1 定理 推导2 De Bruijn定理 定理的特殊情况 CCC上没有置换群 HHH上没有置换群 C,HC,\,HC,H上均没有置换群 例题 分析 写在前面 总结推广 ...

  9. 第7讲 替代定理、戴维南定理、诺顿定理

    替代定理.戴维南定理.诺顿定理 1.替代定理 2.戴维南定理 3.诺顿定理 4.戴维南定理和诺顿定理的等效 1.替代定理 ●内容: 任何一支路可以用一个独立电压源或独立电流源代替,只要电压源的电压等于 ...

最新文章

  1. Java 8 - 06 Lambda 和方法引用实战
  2. Optional 的基本用法
  3. 54款开源服务器软件(内容管理、数据库、电子商务、邮件服务器、文件传输、操作系统、安全、小公司服务 .
  4. VS2017中的附加到进程
  5. 个人应用开发详记. (三)
  6. 关注微信公众号使其自动发送欢迎你关注消息
  7. oracle数据库listener开启和关闭trace文件的方法
  8. 项目开发中XML 读取错误总结
  9. 费率转换成利率的计算器_存款利率计算器
  10. 计算机天空之城音乐谱,天谕手游天空之城乐谱代码是什么
  11. 恶意软件通信协议的应用现状分析
  12. MuMu模拟器Unity Profiler
  13. 计算机网络常见面试题整理
  14. Unrecognized DataType
  15. npm、cnpm、yarn安装指定版本的依赖包
  16. P2392 kkksc03考前临时抱佛脚
  17. Learning to Learn
  18. Python 用3D引擎写一个Pong游戏
  19. 微软、思科等企业源代码被黑客在线售卖,打包价100万美元
  20. scss主题颜色切换

热门文章

  1. 一道积分不等式的最优估计探索
  2. linux ifort编译命令,[Linux] icc与ifort编译器
  3. java转go之初体验(一)
  4. 报错:“TypeError: Cannot read property ‘0‘ of undefined“的原因
  5. js中对数组的增删方法:push(),pop(),unshift(),shift(),splice()的用法小结
  6. 杭州某公司福禄克FLUKE DTX-SFM2单模模块-修复案例
  7. 语音识别ASR和NLP有什么区别?
  8. seo优化教程-免费SEO优化详细教程
  9. TCP FIN_WAIT1状态的实验和验收
  10. 什么是幻读?以及如何解决幻读?