1.Lucas定理

首先给出式子:\(C_n^m\%p = C_{\lfloor\frac{n}{p}\rfloor}^{\lfloor\frac{m}{p}\rfloor} * C_{n\%p}^{m\%p}\% p\),其中p为质数。

这里给出证明……证明是我在luogu上看到的lance1ot大佬的证明,个人认为是写的很好的,在此还要做一下补充。

首先,对于质数p,可以保证\(C_p^i(1 <= i <= p-1) \equiv 0(mod\ p)\),这个比较显然,因为组合数一定是整数,而质数p的因子只有自己和1,也就是说并没有某个数能整除它,所以答案必然是p的倍数。

根据二项式定理,\((1+x)^p = C_p^0x^0 + C_p^1x^1 + C_p^2x^2+…C_p^px^p\),结合上面的结论可以知道\((1+x)^p \equiv 1 + x^p (mod\ p)\)

之后我们要证明lucas定理 ,我们假设\(a = kp + j,b = sp + g\),那我们只要证明\(C_a^b = C_k^s * C_j^g\%p\)即可。

继续从二项式定理入手。\((1+x)^a \equiv (1+x)^{kp+j} \equiv (1+x)^{kp} * (1+x)^j \equiv (1+x^p)^k * (1+x)^j(mod\ p)\)

这时候我们观察二项式展开后第b+1项,就是\(C_a^bx^b\),这项显然也是可以由\((1+x^p)^k\)中的一项和 \((1+x)^j\)中的一项相乘得到的。而且是唯一的两项,就是\(C_k^sx^{sp}\)和\(C_j^gx^g\) ,因为\(b = sp+g\),那么对于\((1+x^p)^k\)的展开式,显然x的指数是\((s+1)p\)或者更高次的指数比b大,而\((s-1)p\)或者更低次的,后面的指数会不够用,也无法匹配成b。所以\(C_a^bx^b \equiv C_k^sx^{sp}*C_j^gx^g(mod\ p)\),那么\(C_a^b \equiv C_k^sx^{sp}*C_j^gx^g(mod\ p)\),即\(C_n^m\%p = C_{\lfloor\frac{n}{p}\rfloor}^{\lfloor\frac{m}{p}\rfloor} * C_{n\%p}^{m\%p}\% p\)。

一开始的前提条件要求了p必须是质数。否则的话\(C_p^i(1 <= i <= p-1) \equiv 0(mod\ p)\)无法保证,因为p很有可能被自己的因子筛掉了。比如\(C_6^4\%6\),答案就是3而不是0.

2.扩展Lucas定理。

当我们遇到p不是质数的时候怎么办呢……

如果p能分解成几个质数的乘积,而且这些质数的指数都是1的话,可以直接套用lucas然后用CRT合并。比如SDOI2010古代猪文

不过如果它可以分解成质数的k次幂的乘积,这样就不行了。

于是我们有了扩展Lucas。

首先我们把p唯一分解,假设我们现在用\(p_i^k\)做模数,把所有的计算出来以后还是可以用CRT合并的。

因为\(C_n^m = \frac{n!}{m!(n-m)!}\),所以问题变成了如何快速在模意义下算出阶乘。

大致的方法就是,首先我们先提取出所有p的倍数,对于n,其阶乘内部有\(\lfloor\frac{n}{p}\rfloor\)个p的倍数,把他们全部提取出来,结果就是\(p^{\lfloor\frac{n}{p}\rfloor} * \lfloor\frac{n}{p}\rfloor!\),其中\(\lfloor\frac{n}{p}\rfloor!\)就可以递归计算。

对于不是p的倍数的,每个\(p^k\)成一个循环节,在每个循环节里面是直接把乘积算出来,最后再套上\(\lfloor\frac{n}{p^k}\rfloor\)的指数。最后会剩余几项,那些直接暴力乘起来就行。

举个例子。(luogu上的例子)

假设\(n = 19,p = 3,k = 2\),首先我们先把p的倍数提取出来,就变成\(1 * 2 * 4 * 5 * 7 * 8 * 10 * 11 * 13 * 14 * 16 * 17 * 19 * 3^6 * 6!\)

之后可以看出\(1 \equiv 10(mod\ 9)\),\(2 \equiv 11 (mod\ 9)\),所以原式就变成\((1 * 2 * 4 * 5 * 7 * 8)^2 * 19 * 3^6 * 6!\)

最后那个单个的19就是不在循环节里面的,但是\(1 \equiv 19(mod\ 9)\)嘛,所以暴力计算就好了啦。

这样递归下去计算就可以。代码实现中略微有些不同,就是对于里面每一次计算次方的\(p^{\lfloor\frac{n}{p}\rfloor}\),我们不在递归的时候计算,而是全部提出来,先上下消去,最后再做乘方。这个看代码实现就好。

这里有一道板子题国家集训队 礼物,答案显然是\(C_n^{w[1]}*C_{n-w[1]}^{w[2]}…\),直接套扩展lucas即可。

#include<bits/stdc++.h>
#define rep(i,a,n) for(ll i = a;i <= n;i++)
#define per(i,n,a) for(ll i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = 1000005;
const int INF = 1000000009;
const double eps = 1e-8; ll read()
{
ll ans = 0,op = 1;char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
return ans * op;
} ll n,m,p,w[105],sum,ans = 1;
ll mul(ll a,ll b,ll t)
{
ll res = a * b - (ll)((long double)a / t * b + eps) * t;
return (res % t + t) % t;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b){x = 1,y = 0;return a;}
ll d = exgcd(b,a%b,y,x);
y -= a / b * x;
return d;
}
ll inv(ll a,ll b)
{
ll x,y;
exgcd(a,b,x,y);
return (x % b + b) % b;
}
ll CRT(ll b,ll t) {return mul(mul(b,inv(p/t,t),p),p/t,p);}
ll qpow(ll a,ll b,ll t)
{
ll p = 1;
while(b)
{
if(b & 1) p = mul(p,a,t);
a = mul(a,a,t),b >>= 1;
}
return p;
} ll fac(ll n,ll pi,ll pk)
{
if(!n) return 1;
ll res = 1;
rep(i,2,pk) if(i % pi) res *= i,res %= pk;
res = qpow(res,n/pk,pk);
rep(i,2,n%pk) if(i % pi) res *= i,res %= pk;
return res * fac(n / pi,pi,pk) % pk;
} ll C(ll n,ll m,ll pi,ll pk)
{
ll d = fac(n,pi,pk),d1 = fac(m,pi,pk),d2 = fac(n-m,pi,pk);
ll k = 0;
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 mul(mul(d,inv(d1,pk),pk),mul(qpow(pi,k,pk),inv(d2,pk),pk),pk);
} ll exlucas(ll n,ll m)
{
ll res = 0,tmp = p,pk;
ll lim = sqrt(p);
rep(i,2,lim) if(!(tmp % i))
{
pk = 1;
while(!(tmp%i)) pk *= i,tmp /= i;
res += CRT(C(n,m,i,pk),pk),res %= p;
}
if(tmp > 1) res += CRT(C(n,m,tmp,tmp),tmp),res %= p;
return res;
} int main()
{
p = read();
n = read(),m = read();
rep(i,1,m) w[i] = read(),sum += w[i];
if(sum > n) printf("Impossible\n"),exit(0);
rep(i,1,m) ans *= exlucas(n,w[i]),ans %= p,n -= w[i];
printf("%lld\n",ans);
return 0;
}

Lucas定理和扩展Lucas定理的更多相关文章

  1. Cayley 定理与扩展 Cayley 定理

    Cayley 定理 节点个数为 \(n\) 的无根标号树的个数为 \(n^{n−2}\) . 这个结论在很多计数类题目中出现,要证明它首先需要了解 \(\text{Prufer}\) 序列的相关内容. ...

  2. 【科技】扩展Lucas随想

    扩展Lucas解决的还是一个很Simple的问题: 求:$C_{n}^{m} \; mod \; p$. 其中$n,m$都会比较大,而$p$不是很大,而且不一定是质数. 扩展Lucas可以说和Luca ...

  3. 2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理)

    J. Ceizenpok’s formula time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. 【learning】 扩展lucas定理

    首先说下啥是lucas定理: $\binom n m \equiv \binom {n\%P} {m\%P} \times \binom{n/P}{m/P} \pmod P$ 借助这个定理,求$\bi ...

  5. [学习笔记]扩展LUCAS定理

    可以先做这个题[SDOI2010]古代猪文 此算法和LUCAS定理没有半毛钱关系. [模板]扩展卢卡斯 不保证P是质数. $C_n^m=\frac{n!}{m!(n-m)!}$ 麻烦的是分母. 如果互 ...

  6. BZOJ - 2142 礼物 (扩展Lucas定理)

    扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...

  7. [bzoj2142]礼物(扩展lucas定理+中国剩余定理)

    题意:n件礼物,送给m个人,每人的礼物数确定,求方案数. 解题关键:由于模数不是质数,所以由唯一分解定理, $\bmod  = p_1^{{k_1}}p_2^{{k_2}}......p_s^{{k_ ...

  8. Ceizenpok’s formula Gym - 100633J 扩展Lucas定理 + 中国剩余定理

    http://codeforces.com/gym/100633/problem/J 其实这个解法不难学的,不需要太多的数学.但是证明的话,我可能给不了严格的证明.可以看看这篇文章 http://ww ...

  9. [笔记] 扩展Lucas定理

    [笔记] 扩展\(Lucas\)定理 \(Lucas\)定理:\(\binom{n}{m} \equiv \binom{n/P}{m/P} \binom{n \% P}{m \% P}\pmod{P} ...

随机推荐

  1. 11gR2 RAC 独占模式replace votedisk遭遇PROC-26,restore ocr遭遇CRS-4000、PROT-35

    原文链接:http://blog.itpub.net/23135684/viewspace-748816/ 11gR2 RAC系统的存储数据全然丢失,全部节点的软件都安装在本地磁盘中.本地磁盘保留了O ...

  2. DICOM:DICOM Print 服务详细介绍

      目录(?)[-] 背景 DICOM Print服务数据流 DICOM Print服务各部分关系 DICOM Print服务具体实现   背景: 昨天专栏中发表了一篇关于DICOM Print的博文 ...

  3. js:深入继承

    /**  * js实现继承:  * 1.基于原型链的方式  * 2.基于伪造的方式  * 3.基于组合的方式  */ 一.基于原型链的方式 function Parent(){   this.pv = ...

  4. C# 解析迅雷链接成正常的Http链接

    目前热门剧司马懿第一集的迅雷下载地址是: thunder://QUFodHRwOi8vZGwxMjIuODBzLmltOjkyMC8xNzA2L1vlpKflhptTU+mprOaHv+S5i+WGm ...

  5. C语言-回溯例1

    回溯法解N皇后问题 1,代码分析: 使用一个一维数组表示皇后的位置 其中数组的下标表示皇后所在的行 数组元素的值表示皇后所在的列 这样设计的棋盘,所有皇后必定不在同一行 假设前n-1行的皇后已经按照规 ...

  6. mysql + php 中文乱码 全是? 解决方法

    在my.ini文件中找到[client]和[mysqld]字段,在下面均加上default-character-set=utf8,保存并关闭,重启服务器 在window下重启失败,这是因为你安装了高版 ...

  7. FastDFS的配置、部署与API使用解读(8)FastDFS多种文件上传接口详解(转)

    1.StorageClient与StorageClient1的区别 相信使用happy_fish的FastDFS的童鞋们,一定都熟悉StorageClient了,或者你熟悉的是StorageClien ...

  8. Django-中介模型

    有多对多字段的时候自己创建的第三章表就是中介模型 class Article(models.Model): ''' 文章表 ''' title = models.CharField(max_lengt ...

  9. 基于HTML,css,jQuery,JavaScript,MySQL搭建博客系统

    一.登陆注册 二.登录验证码相关 三.博客首页显示相关 四.当前用户的家目录显示 五.点赞以及取消 六.父评论以及子评论操作 七.后台管理首页 八.文章的操作(增.删,改) 九.文件上传问题 十.me ...

  10. Markov Decision Processes

    为了实现某篇论文中的算法,得先学习下马尔可夫决策过程~ 1. https://leonardoaraujosantos.gitbooks.io/artificial-inteligence/conte ...