扩展卢卡斯定理(Exlucas)
题目链接
前置知识
- 中国剩余定理(crt)或扩展中国剩余定理(excrt)
- 乘法逆元
- 组合数的基本运用
- 扩展欧几里得(exgcd)
说实话Lucas真的和这个没有什么太大的关系,但是Lucas还是要学学的:戳我
正文
题目是要求:
\]
如果这个p是质数的话那太简单了,直接Lucas就好了,但问题是现在p不一定是一个质数。
我们令 \(P=\prod {p_i}^{c_i}\)
我们如果知道每个\(c_n^m mod \ p_i^{c_i}\)的值的话就可以根据中国剩余定理求出答案
那我们怎么求出这个值呢?
我们可以将\(c_n^m\)写成\(\frac{n!}{m!(n-m)!}\)
现在我们可以处理阶乘的模。那么如何处理阶乘的模呢?
举个经典例子:
\(p=3,n=19,c=2\)时
我们可以吧式子写成这样:
\]
\]
我们可以将他分为几个部分
\]
我们会发现对于每一个整的部分如\((8*7*5*4*2*1)\)的模数都是一样的,于是这一块我们可以运用快速幂,而剩余的\(19\)我们可以进行暴力。对于\(6!\)我们可以继续递归求解,那么怎么分组呢
我们可以把每一段的范围定为\(p^c\)。差不多就这样吧。
code
#include<bits/stdc++.h>
#define rg register
#define int long long
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return f*x;
}
inline void exgcd(int a,int b ,int &x,int &y){
if(!b){x=1,y=0;return;}
exgcd(b,a%b,x,y);
int t=x;
x=y,y=t-(a/b)*y;
}
inline int inv(int a,int b){
int x,y;
return exgcd(a,b,x,y),(x%b+b)%b;
}
inline int ksm(int a,int b,int p){
int ans=1;
while(b){
if(b&1)
ans=a*ans%p;
a=a*a%p;
b>>=1;
}
return ans%p;
}
inline int crt(int x,int p,int mod){
return inv(p/mod,mod)*(p/mod)*x;
}
inline int fac(int x,int a,int b){
if(!x)
return 1;
int ans=1;
for(int i=1;i<=b;i++)
if(i%a)
ans*=i,ans%=b;
ans=ksm(ans,x/b,b);
for(int i=1;i<=x%b;i++)
if(i%a)
ans*=i,ans%=b;
return ans*fac(x/a,a,b)%b;
}
inline int C(int n,int m,int a,int b){
int N=fac(n,a,b),M=fac(m,a,b),Z=fac(n-m,a,b),sum=0;
for(int i=n;i;i=i/a)
sum+=i/a;
for(int i=m;i;i=i/a)
sum-=i/a;
for(int i=n-m;i;i=i/a)
sum-=i/a;
return N*ksm(a,sum,b)%b*inv(M,b)%b*inv(Z,b)%b;
}
inline void exlucas(int n,int m,int p){
int t=p,ans=0;
for(int i=2;i*i<=p;i++){
int k=1;
while(t%i==0)
k*=i,t/=i;
ans+=crt(C(n,m,i,k),p,k),ans%=p;
}
if(t>1)
ans+=crt(C(n,m,t,t),p,t),ans%=p;
printf("%d",ans%p);
}
main(){
int n=read(),m=read(),p=read();
exlucas(n,m,p);
return 0;
}
扩展卢卡斯定理(Exlucas)的更多相关文章
- 【学习笔记】扩展卢卡斯定理 exLucas
引子 求 \[C_n^m\ \text{mod}\ p \] 不保证 \(p\) 是质数. 正文 对于传统的 Lucas 定理,必须要求 \(p\) 是质数才行.若 \(p\) 不一定是质数,则需要扩 ...
- 【知识总结】扩展卢卡斯定理(exLucas)
扩展卢卡斯定理用于求如下式子(其中\(p\)不一定是质数): \[C_n^m\ mod\ p\] 我们将这个问题由总体到局部地分为三个层次解决. 层次一:原问题 首先对\(p\)进行质因数分解: \[ ...
- bzoj2142 礼物——扩展卢卡斯定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2142 前几天学了扩展卢卡斯定理,今天来磕模板! 这道题式子挺好推的(连我都自己推出来了) , ...
- 卢卡斯定理&扩展卢卡斯定理
卢卡斯定理 求\(C_m^n~mod~p\) 设\(m={a_0}^{p_0}+{a_1}^{p_1}+\cdots+{a_k}^{p_k},n={b_0}^{p_0}+{b_1}^{p_1}+\cd ...
- LG4720 【模板】扩展卢卡斯定理
扩展卢卡斯定理 求 \(C_n^m \bmod{p}\),其中 \(C\) 为组合数. \(1≤m≤n≤10^{18},2≤p≤1000000\) ,不保证 \(p\) 是质数. Fading的题解 ...
- 洛谷 P4720 【模板】扩展 / 卢卡斯 模板题
扩展卢卡斯定理 : https://www.luogu.org/problemnew/show/P4720 卢卡斯定理:https://www.luogu.org/problemnew/show/P3 ...
- CRT中国剩余定理 & Lucas卢卡斯定理
数论_CRT(中国剩余定理)& Lucas (卢卡斯定理) 前言 又是一脸懵逼的一天. 正文 按照道理来说,我们应该先做一个介绍. 中国剩余定理 中国剩余定理,Chinese Remainde ...
- P4720【模板】扩展卢卡斯,P2183 礼物
扩展卢卡斯定理 最近光做模板了 想了解卢卡斯定理的去这里,那题也有我的题解 然而这题和卢卡斯定理并没有太大关系(雾 但是,首先要会的是中国剩余定理和exgcd 卢卡斯定理用于求\(n,m\)大,但模数 ...
- [学习笔记]扩展LUCAS定理
可以先做这个题[SDOI2010]古代猪文 此算法和LUCAS定理没有半毛钱关系. [模板]扩展卢卡斯 不保证P是质数. $C_n^m=\frac{n!}{m!(n-m)!}$ 麻烦的是分母. 如果互 ...
随机推荐
- 在工作表左侧中添加TreeView控件
开发环境基于VSTO:visual studio 2010,VB .Net,excel 2007,文档级别的定制程序. 需求是在sheet的左侧停靠System.Windows.Forms.TreeV ...
- git 批量删除本地分支
git branch | grep 'bug' |xargs git branch -D
- yield-from示例
#!/usr/bin/python3# -*- coding: utf-8 -*-# @Time : 2018/6/20 9:13# @File : yield_from11.py fro ...
- Proxmark3笔记(一)
Kali下使用Proxmark3 apt-get update apt-get install build-essential libreadline5 libreadline-dev libusb- ...
- vue-cli中的babel配置文件.babelrc详解
本文介绍vue-cli脚手架工具根目录的babelrc配置文件 介绍 es6特性浏览器还没有全部支持,但是使用es6是大势所趋,所以babel应运而生,用来将es6代码转换成浏览器能够识别的代码 ba ...
- python使用multiprocessing进行多进程编程(1)
multiprocessing模块实现了对多进程编程的封装,让我们可以非常方便的使用多进程进行编程.它的使用方法非常类似threading模块. 1.创建一个进程 import multiproces ...
- Unable to find required classes (javax.activation.DataHandler and javax.mail.internet.MimeMultipart)
在接触WebService时值得收藏的一篇文章: 在调试Axis1.4访问WebService服务时,出现以下错误: Unable to find required classes (javax.ac ...
- Eclipse 控制台不显示打印信息的处理方法
1.进windows菜单 -> show view -> console2.还是windows菜单里面 -> preferences -> 打开左边的run/debug -&g ...
- Splay树分析
简述 Splay树是一种二叉查找平衡树,其又名伸展树,缘由是对其进行任意操作,树的内部结构都会发生类似伸张的动作,换言之,其读和写操作都会修改树的结构.Splay树拥有和其它二叉查找平衡树一致的读写时 ...
- LoadRunner 学习(基础一)
最近开始正式系统地学习LoadRunner11.本想在自己觉得确实学到了比较有成就感的时候再mark一下,写个博客分享.阶段性地或者在自己有所小收获的时候,做做笔记分享下也好.这次作为开篇,我想记录下 ...