卢卡斯定理&扩展卢卡斯

  • Lucas
  • EXlucas
    • 例题

Lucas

卢卡斯定理:

( m n ) = ( m p n p ) ∗ ( m ( m o d p ) n ( m o d p ) ) ( m o d p ) (^n_m)=(^{\frac{n}{p}}_{\frac{m}{p}}) * (^{n \pmod p}_{m \pmod {p}})\pmod p (mn​)=(pm​pn​​)∗(m(modp)n(modp)​)(modp)

后面部分可以递归,就是n和m在p进制下每一位的对应的组合数

证明要二项式定理

条件是P是质数

代码:

ll C(ll s,ll t){if(s>t) return 0;if(s==t) return 1;return (f[t]*g[s])%p*g[t-s]%p;
}
ll lucas(ll s,ll t){if(s==0) return 1;pp=s%p;qq=t%p;//printf("%lld %lld\n",s,t);return C(pp,qq)*lucas(s/p,t/p)%p;   //C处理出0~p-1的阶乘与其逆元就好
}

复杂度大概是 O log ⁡ p O \log p Ologp?

EXlucas

处理p不为质数,考虑把p分解为

p = ∏ i − 1 k p i e i p=\prod^{k}_{i-1}p_i^{e_i} p=i−1∏k​piei​​

然后对于每个质数的乘积求出 ( m n ) ( m o d p i e i ) (^n_m)\pmod {p_i^{e_i}} (mn​)(modpiei​​),用CRT合并

每个质因子乘积的 ( m n ) ( m o d p i e i ) (^n_m)\pmod {p_i^{e_i}} (mn​)(modpiei​​)为
n ! m ! ∗ ( n − m ) ! ( m o d p i e i ) \frac{n!}{m!*(n-m)!} \pmod {p_i^{e_i}} m!∗(n−m)!n!​(modpiei​​)

考虑对于 x ! ( m o d p i e i ) x! \pmod {p_i^{e_i}} x!(modpiei​​),有

x ! = ∏ i = 1 , i ( m o d p ) ! = 0 p k i ( m o d p ) x p ∗ ∏ i = x p + 1 x i ( m o d p ) ∗ p n p ∗ x p ! x! = {\prod^{p^k}_{i=1,i\pmod p !=0} i\pmod p}^{\frac{x}{p}}*\prod_{i=\frac{x}{p}+1}^x i\pmod p *{p^{\frac{n}{p}}} *\frac{x}{p} ! x!=i=1,i(modp)!=0∏pk​i(modp)px​∗i=px​+1∏x​i(modp)∗ppn​∗px​!

举个例子,
当 n = 19 , p = 3 , k = 2 n=19,p=3,k=2 n=19,p=3,k=2时:

n ! = 1 ∗ 2 ∗ 3 ∗ ⋯ ∗ 19 n!=1*2*3*\cdots*19 n!=1∗2∗3∗⋯∗19
= ( 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 ∗ 10 ∗ 11 ∗ 13 ∗ 14 ∗ 16 ∗ 17 ∗ 19 ) ∗ 3 6 ∗ 6 ! =(1*2*4*5*7*8*10*11*13*14*16*17*19)*3^{6}*6! =(1∗2∗4∗5∗7∗8∗10∗11∗13∗14∗16∗17∗19)∗36∗6!
≡ ( 1 ∗ 2 ∗ 4 ∗ 5 ∗ 7 ∗ 8 ) 2 ∗ 19 ∗ 3 6 ∗ 6 ! \equiv(1*2*4*5*7*8)^2*19*3^6*6! ≡(1∗2∗4∗5∗7∗8)2∗19∗36∗6!

然后发现x必须先要和p互质,
于是上面 p n p p^{\frac{n}{p}} ppn​就不算了

然后最后在外面补一个

复杂度PlogP的

看代码:

#include<bits/stdc++.h>
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define ll long long
ll test[15]={0,2,61,23,37};
inline ll read(){ll x=0;int pos=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0 ;for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';return pos?x:-x;
}
ll n,m,p;
void exgcd(ll a,ll b,ll &x,ll &y){if(!b) x=1,y=0;else{exgcd(b,a%b,y,x);y-=x*(a/b);}
}
ll ksm(ll aa,ll bb,ll mod){ll nans=1;while(bb){if(bb&1) nans=(nans*aa)%mod;aa=(aa*aa)%mod;bb>>=1;}return nans;
}
ll inv(ll xx,ll mod){ll x,y;exgcd(xx,mod,x,y);return (x%mod+mod)%mod;
}
ll fac(ll xx,ll pi,ll pk){if(!xx) return 1;ll res=1;for(ll i=2;i<=pk;++i){if(i%pi!=0) res=(res*i)%pk; }res=ksm(res,xx/pk,pk);for(ll i=2;i<=xx%pk;++i){if(i%pi!=0) res=(res*i)%pk;}return res*fac(xx/pi,pi,pk)%pk;
}
ll C(ll n,ll m,ll pi,ll pk){ll up=fac(n,pi,pk),d1=fac(m,pi,pk),d2=fac(n-m,pi,pk);ll resp=0;for(ll i=n;i;i/=pi) resp+=i/pi;for(ll i=m;i;i/=pi) resp-=i/pi;for(ll i=n-m;i;i/=pi) resp-=i/pi;return up*inv(d1,pk)%pk*inv(d2,pk)*ksm(pi,resp,pk)%pk;
}
ll CRT(ll b,ll mod){return b*inv(p/mod,mod)%p*(p/mod)%p;
}
ll out(ll aa){if(aa>9) out(aa/10);putchar(aa%10+'0');
}
ll work(ll n,ll m){ll res=0,tmp=p,pk=1;int len=sqrt(p);for(register int i=2;i<=len;++i){if(tmp%i==0){pk=1;while(tmp%i==0) pk*=i,tmp/=i;int pp=i;res=(res+CRT(C(n,m,pp,pk),pk))%p; }    }if(tmp>1){int pp=tmp;pk=tmp;res=(res+CRT(C(n,m,pp,pk),pk))%p; }return res;
}
int main(){n=read();m=read();p=read();out(work(n,m));return 0;
}

例题

luogu2183 [国家集训队] 礼物

基本裸的,不难看出组合数的方案,重点在于取模

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#define rep(i,a,b) for(long long i=(a);i<=(b);++i)
#define per(i,a,b) for(long long i=(a);i>=(b);--i)
#define ll long long
long long read(){long long x=0,pos=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';return pos?x:-x;
}
using namespace std;
ll n,m,mod,w[10];
ll ksm(ll a,ll b,ll mo){ll na=1;while(b){if(b&1){na=(na*a)%mo;}a=(a*a)%mo;b>>=1;}return na;
}
ll fac(ll n,ll pi,ll pk){if(!n) return 1;ll res=1;rep(i,2,pk) if(i%pi) res=(res*i)%pk;res=ksm(res,n/pk,pk);rep(i,2,n%pk) if(i%pi) res=(res*i)%pk;return res*fac(n/pi,pi,pk)%pk;
}
void exgcd(ll a,ll b,ll &x,ll &y){if(b==0) x=1,y=0;else exgcd(b,a%b,y,x),y-=x*(a/b);
}
ll inv(ll now,ll mo){ll x,y;exgcd(now,mo,x,y);return (x%mo+mo)%mo;
}
ll C(ll n,ll m,ll pi,ll pk){ll up=fac(n,pi,pk),d1=fac(m,pi,pk),d2=fac(n-m,pi,pk);ll resp=0;for(int i=n;i;i/=pi) resp+=i/pi;for(int i=m;i;i/=pi) resp-=i/pi;for(int i=n-m;i;i/=pi) resp-=i/pi;return up*inv(d1,pk)%pk*inv(d2,pk)%pk*ksm(pi,resp,pk)%pk;
}
ll CRT(ll a,ll b){return a*inv(mod/b,b)%mod*(mod/b)%mod;
}
ll exlucas(ll n,ll m,ll p){ll pk=1,res=0,tmp=p;int len=sqrt(p);rep(i,2,len){if(tmp%i==0){pk=1;while(tmp%i==0) tmp/=i,pk*=i;ll Ci=C(n,m,i,pk);res=(res+CRT(Ci,pk))%p;}}if(tmp>1){ll Ci=C(n,m,tmp,tmp);res=(res+CRT(Ci,tmp))%p;}return res;
}
int main(){mod=read();n=read();m=read();rep(i,1,m){w[i]=read();}ll ans=1,tot=0;rep(i,1,m){if(n<tot+w[i]){printf("Impossible");return 0;}ans=ans*(exlucas(n-tot,w[i],mod))%mod;tot+=w[i];}printf("%lld",ans);return 0;
}

卢卡斯定理扩展卢卡斯相关推荐

  1. 『数学』--数论--组合数+卢卡斯定理+扩展卢卡斯定理

    组合数: 在N个数中选取M个数,问选的方式有几种? 直接递归暴力简单 #include<cstdio> const int N = 2000 + 5; const int MOD = (i ...

  2. 卢卡斯定理及其卢卡斯定理的拓展

    前言: 求一个组合数 ,我们可以通过逆元的方式在 O(n)的时间复杂度内求出 但如果数特别大时(数据范围 ),又该怎么办 使用卢卡斯定理求解 卢卡斯定理:(组合数取模,取模的模数只能是质数) 即  模 ...

  3. 《夜深人静写算法》数论篇 - (22) 卢卡斯定理

    文章目录 前言 一.问题引入 1.递推公式 2.通项公式 二.卢卡斯定理 1.定义 2.证明 1)引理1 2)引理2 3)卢卡斯定理 前言     卢卡斯定理,ACM刷题中遇到过,用于组合数取模. 一 ...

  4. P4720 【模板】扩展卢卡斯定理/exLucas(无讲解,纯记录模板)

    P4720 [模板]扩展卢卡斯定理/exLucas 题意: CnmmodpC_{n}^{m}\bmod pCnm​modp 对于 100% 的数据,1≤m≤n≤1018,2≤p≤106,不保证 p 是 ...

  5. 组合数学 —— 组合数取模 —— 卢卡斯定理与扩展卢卡斯定理

    [卢卡斯定理] 1.要求:p 是质数,m.n 很大但 p 很小 或者 n.m 不大但大于 p 2.定理内容 其中, 3.推论 当将 n 写成 p 进制:,将 m 写成 p 进制: 时,有: 4.实现 ...

  6. 洛谷 P4720 【模板】扩展卢卡斯定理/exLucas

    [模板]扩展卢卡斯定理/exLucas 题目背景 这是一道模板题. 题目描述 求 Cnmmodp{\mathrm{C}}_n^m \bmod{p}Cnm​modp 其中 C\mathrm{C}C 为组 ...

  7. 【知识总结】扩展卢卡斯定理(exLucas)

    扩展卢卡斯定理用于求如下式子(其中 p p p不一定是质数): C n m m o d p C_n^m\ mod\ p Cnm​ mod p 我们将这个问题由总体到局部地分为三个层次解决. 层次一:原 ...

  8. 【数学】扩展卢卡斯定理

    Description 求 ( n m ) m o d p \dbinom{n}{m}\bmod p (mn​)modp 其中 p p p 较小且 不保证 p p p 是质数. Method 前置芝士 ...

  9. 组合数求解与(扩展)卢卡斯定理

    前言: 咳咳咳咳 ,最近瘟疫盛行,围观的记得要戴口罩. 求解组合数的方法大家应该都见了很多了,这篇博客将围绕这个问题进行归纳和深入学习. 问题: 给定 n , k , p n,k,p n,k,p求解组 ...

最新文章

  1. 为什么产品经理面试都喜欢问注册问题?
  2. SAP UI5 视图如何使用工程里的 sample data 作为 JSON model 的数据源
  3. 图片外链测试-HTML
  4. 洛谷 题解 P2312 【解方程】
  5. mybatis基础,mybatis核心配置文件properties元素
  6. 每日算法系列【LeetCode 992】K个不同整数的子数组
  7. c语言中,x-y,'105',ab,7f8那个是正确的,C语言习题册
  8. 机器学习什么显卡_机器学习之多显卡加速运算(Pytorch版)
  9. 【Matlab身份证识别】BP神经网络身份证号码识别【含源码 1344期】
  10. Java用while求100以内奇数和
  11. 如何用电子书来做网络营销
  12. 不同电脑进入bios按键汇总
  13. 丘成桐女子中学生数学竞赛结果出炉,人大附中拿下金奖,上海4人入围
  14. IntelliJ IDEA 在 Project 选项卡中查找快捷键
  15. java实现单个或多个文件的压缩、解压缩 支持zip、rar等格式
  16. 如何快速打造一个高权重的短视频账号?短视频运营推广日记(2)
  17. Java高级--->多线程的学习
  18. jdk1.7升级jdk1.8
  19. 深入浅出Viterbi算法与python实现
  20. 使用Promise.race()实现控制并发

热门文章

  1. 解决 Spring Cloud 整合 zipkin 报错:org.springframework.boot.actuate.health.CompositeHealthIndicator......
  2. 开源了自己开发的后台管理系统
  3. 4个精品微信小程序推荐,用过以后根本离不开!
  4. 服务器(CentOS7)配置安装oracle12c(v12.2.0)
  5. 嵌入式开发——rtc时钟调试笔记
  6. 微信小程序入门实例--地图
  7. JAVA语言异常_Java语言中常用异常类EoFException是用来处理( )异常的类_学小易找答案...
  8. 商业大数据分析报告选题与背景撰写技巧
  9. 用Postman查询RPC常用方法
  10. ChatGPT团队揭秘:3清华、1北大、1华科