[学习笔记]扩展LUCAS定理
可以先做这个题[SDOI2010]古代猪文
此算法和LUCAS定理没有半毛钱关系。
【模板】扩展卢卡斯
不保证P是质数。
$C_n^m=\frac{n!}{m!(n-m)!}$
麻烦的是分母。
如果互质就有逆元了。
所以可以考虑把分子分母不互质的数单独提出来处理。
然鹅P太一般,直接处理要考虑的东西太多。
我们不妨令$p=p_1^{q_1}*p_2^{q_2}*...*p_k^{q_k}$
对每一个$p_i^{q_i}$分别求解(不妨叫这个数为$pk$)(这样会容易很多)
即求ai满足:$\frac{n!}{m!(n-m)!} = a_i\space mod \space pk$
然后可以$CRT$合并
(CRT可以合并的原因是,我们可以求出满足这些同余方程的通解。发现这些解mod lcm都是同一个数x。$C_n^m$一定是这些个解之一,不管是哪一个,$mod\space lcm$即mod p都是x。我们也就求出了答案)
$\frac{n!}{m!(n-m)!} = a_i\space mod \space pk$
现在不互质的就是pi的倍数
首先我们可以把分子分母的所有$pi$质因子都提出来,然后上下次数相消。
对于$n!$中p的质因个数,就是不断除以p^i下取整。
剩下的都是和pk互质的了。存在逆元
以求$19!\space mod\space 3^2$为例
$19!=1*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19$
提完质数3之后,变成:
$=(1*2*3*4*5*6)*3^2*(1*2*4*5*7*8*10*11*13*14*16*17*19)$
前面直接递归下去处理。后面的每一项,都可以%pk处理。
(不论分母还是分子位置,如果是分母位置,因为存在逆元,
10*inv =1 mod 9
1*inv = 1 mod 9
这两个inv显然是同一个inv.所以把所有项%pk没有问题
)
然后变成:
$=(1*2*3*4*5*6)*3^2*(1*2*4*5*7*8)^2*1)$
后面那个1是多出来的19
其实pk长度的循环节有n/pk个。直接算。剩下(例如这里的19),个数少于pk,直接算。
(所以,扩展LUCAS的重要适用条件是,$p_i^{q_i}$不能太大(1e5左右))
递归算出来即可。
对于分母位置的两个阶乘,算出来结果之后,再处理inv
(这里可以先乘完之后再找inv,不用一边找inv一边乘。)
(注意inv处理要用exgcd,不保证质数,不能用费马)
(CRT可以不用保存结果,Mi=p/pk 可以一次到位)
#include<bits/stdc++.h> #define reg register int #define il inline #define int long long #define numb (ch^'0') using namespace std; typedef long long ll; il void rd(int &x){char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x); } namespace Miracle{ ll p; ll qm(ll x,ll y,ll pk){x%=pk;ll ret=1;while(y){if(y&1) ret=(ret*x)%pk;x=(x*x)%pk;y>>=1;}return ret; } ll calc(ll n,ll pi,ll pk){//计算阶乘部分 (质因子已经提前处理这里不予考虑) if(!n) return 1;ll res=1;for(reg i=2;i<pk;++i)//每个循环节 if(i%pi) res=(res*i)%pk;res=qm(res,n/pk,pk);for(reg i=2;i<=n%pk;++i)if(i%pi) res=(res*i)%pk;return res*calc(n/pi,pi,pk)%pk; } void exgcd(ll a,ll b,ll &x,ll &y){//exgcdif(!b){x=1,y=0;return;}exgcd(b,a%b,y,x);y-=(a/b)*x; } ll inv(ll n,ll pk){//逆元 ll x,y;exgcd(n,pk,x,y);x=(x%pk+pk)%pk;return x; } ll C(ll n,ll m,ll pi,ll pk){//计算C(n,m)mod pi^k ll up=calc(n,pi,pk),d1=calc(m,pi,pk),d2=calc(n-m,pi,pk);ll k=0;for(reg i=n;i;i/=pi) k+=i/pi;//处理质因子个数 for(reg i=m;i;i/=pi) k-=i/pi;for(reg i=n-m;i;i/=pi) k-=i/pi;return up*inv(d1,pk)%pk*inv(d2,pk)%pk*qm(pi,k,pk)%pk; }ll CRT(ll b,ll mod){//CRT每步算出来了之后直接合并 return (b*inv(p/mod,mod)%p*(p/mod))%p; } ll EXLUCAS(ll n,ll m){//质因数分解+开始处理C ll ret=0;ll tmp=p;for(reg i=2;(ll)i*i<=tmp;++i){if(tmp%i==0){ll pi=i,pk=1;while(tmp%i==0) pk*=i,tmp/=i;(ret+=CRT(C(n,m,pi,pk),pk))%=p;}}if(tmp>1) (ret+=CRT(C(n,m,tmp,tmp),tmp))%=p;return ret; } int main(){ll n,m;scanf("%lld%lld%lld",&n,&m,&p);printf("%lld",EXLUCAS(n,m));return 0; }} signed main(){Miracle::main();return 0; }/*Author: *Miracle*Date: 2018/12/1 8:44:42 */
这个算法的核心思路是:
1.不互质的要提出来单独处理
2.直接处理P,不互质的太多了
3.分成质因子处理,CRT合并
4.对于阶乘上下提出不互质的部分(质因子),转化成互质存在逆元的情况
5.观察剩余部分,后面可以对pk取模。
发现一部分还是阶乘,递归处理。
另一部分发现有循环节,利用循环节加速处理。
剩下的边角考虑一下。
(5本质上就是对每个数提取pi质因子,剩下的再乘起来。不过用递归和循环节加速了一下)
还有一个无聊的题:
[国家集训队]礼物
简单的组合数学,非要考你扩展LUCAS。。。。
转载于:https://www.cnblogs.com/Miracevin/p/10049729.html
[学习笔记]扩展LUCAS定理相关推荐
- 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 ...
- lucas定理及扩展lucas定理
还有一篇关于lucas定理的比较好的文章:关于LUCAS二项式系数同余定理的一些推广 转载原文链接:http://www.cnblogs.com/jianglangcaijin/p/3446839.h ...
- BZOJ 4338 糖果(扩展Lucas定理+CRT)
题目链接:BZOJ 4338 题目大意:用数字1~k填一个n*m的表格,每种数字可用任意次,要求每行数字1~m列单调不减,任意两行不完全相同,求方案数对P取模的值. 题解:扩展Lucas+CRT模板题 ...
- 扩展Lucas定理 扩展Lucas板子
题意概述:多组询问,给出N,K,M,要求回答C(N,K)%M,1<=N<=10^18,1<=K<=N,2<=M<=10^6 分析: 模数不为质数只能用扩展Lucas ...
- 【学习笔记】Dilworth 定理的构造性证明
发现自己并不会 Dilworth 定理的构造性证明(原题要求输出方案),于是去 Wiki 上学习了一下.下文是我参照 Wiki 上的证明思路口胡的一个证明. 附例题:Codeforces 590E D ...
- [学习笔记] Matrix tree定理
前言 为了回归算法本身,为了搞懂算法,我参考了不同博客,并将他们做出整合和补充: https://www.luogu.com.cn/blog/tanrui-2960967961/matrix-tree ...
- 【学习笔记】Sperner定理及其证明
额,最近看到了一个十分有趣的定理--Sperner定理.其实这个定理在OI中没什么用处,因此我都没把这篇文章放到我的OI标签里(不知道在MO中是否有用?)但是觉得它很有趣于是就过来写一下. 由于博主太 ...
- [学习笔记] 二分图基础定理的相关证明
最小点集覆盖=最大匹配 最小点集覆盖:选出最少的点使得每条边都至少有一个端点被选. 先证最小点集覆盖 ≥\ge≥ 最大匹配 假设最大匹配为 xxx,即有 xxx 条边两两之间没有公用点. 光覆盖这些边 ...
- 概率论学习笔记之李雅普诺夫定理
定理二(李雅普诺夫定理) 设随机变量X1,X2,-,Xn,-.相互独立,它们具有数学期望和方差 二项分布近似正态分布 例如:
最新文章
- 操作系统学习笔记 第二章:进程管理(王道考研)
- 前端学习(1401):多人管理21新增用户
- 量子计算机九章能否预测未来,张礼立 : 中国 “九章”量子计算机到底厉害在哪?...
- python实现雪花飘落的效果_使用javascript实现雪花飘落的效果
- MongoDB 教程五: MongoDB固定集合和性能优化
- new to python什么意思_Python中__new__的作用
- (Zotero)开源的文献管理器 真香
- Prefer rather than 喜欢 Prefer to
- python 3.8.2安装教程
- Oracle12C日志出现error=904怎样解决
- CRM系统之数据库设计
- Windows系统目录及常用快捷键
- 关于arctanx的麦克劳林展开式推导
- 阿里云服务器和腾讯云不同的地方
- PCIe功耗控制--ASPM
- node联合echarts简单实现疫情地图
- WeiXin miniApp Shortcuts
- Python性能分析优化及测试
- mysql导入sql文件、数据库时报错ERROR: ASCII ‘\0‘ appeared in the statement
- 小黄豆CRM是什么?
热门文章
- MINIGUI交叉编译【转】
- Android Handler的内存泄露场景分析
- Nginx 与 Tomcat,Apache的区别
- 基于TCP协议用多线程实现并发服务器,实现思路、算法和demo
- 【kafka】kafka消费者报错INVALID_FETCH_SESSION_EPOCH
- 【Flink】flink-1.12 通过 -t 指定模式后无法指定yarn参数
- 【java】Java8 BiConsumer函数式接口
- 【clickhouse】Clickhouse 支持毫秒 纳秒数据
- 【Kafka】Kafka Streams简介
- Maven: maven parent.relativepath point at wrong local pom