P3807【模板】卢卡斯定理
题解大部分都是递归实现的,给出一种非递归的形式
话说上课老师讲的时候没给代码,然后自己些就写成了这样
对于质数\(p\)给出卢卡斯定理:
\]
其实它还有另一种形式,虽然本质上没啥区别:
\]
其中,\(a,b\)分别为\(n,m\)的\(p\)进制下的每一位,\(k\)是它们位数的较大值,当然如果有数不足\(k\)位,要补前导0
来证明一下
其实证明方法也是看了别人blog才知道的
设\(s=\lfloor \dfrac{n}{p}\rfloor,t=\lfloor \dfrac{m}{p}\rfloor\)
则有\(q,w\)使得\(n=sp+q,m=tp+w\)
再考虑一个二项式:
\]
先由费马小定理推个结论:
\]
\]
所以:
\]
把这个结论带进去:
\]
再由二项式定理把右边展开
\]
同样我们可以把左边展开:
\]
然后我们可以发现,左右两遍都有\(x^{tp+w}\)次项(当然,这是在\(m\leq n\)的情形下,如果\(m>n\)结果就是0,不用考虑了)
比较一下它们的系数
左边:\(\tbinom{sp+q}{tp+w}x^{tp+w}\)
右边:\(\tbinom{s}{t}x^{tp}\cdot \tbinom{q}{w}x^w\)
这边要说明一下,不会出现别的次数组合,比如\((t-1)p\)和\((w+p)\),因为\(w,q<p\)
所以:\(\tbinom{sp+q}{tp+w}\equiv \tbinom{s}{t}\tbinom{q}{w}\pmod p\)
即:
\]
然后把\(\tbinom{\lfloor \frac{n}{p}\rfloor}{\lfloor \frac{m}{p} \rfloor}\)这一项不断展开,其实就变为了那种非递归形式
好了,我们终于得到了这个定理
那写代码就简单了,将\(n,m\)转化为\(p\)进制
预处理出阶乘数组,和阶乘的逆元数组
然后对于这\(p\)进制的每一位直接套组合数公式就行了
然而代码似乎没有递归的好写
另外一共5个点,我错了三遍下载了三个数据来调
那么说一下踩得坑,首先主函数for
循环里的特判一定要有,避免出现数组下标变成负数,或者使用0的逆元的情况
还有多测时前导0的位置一定要清零
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<stack>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
int x=0,y=1;
char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
int n,m,p;
LL fac[200006],g[200006];
int a[100006],b[100006];
inline LL power(LL x,LL y){
reg LL ans=1;
while(y){
if(y&1) ans=(1ll*ans*x)%p;
y>>=1;x=(x*x*1ll)%p;
}
return ans;
}
std::stack<int>s;
inline void pre(){//预处理函数
a[0]=b[0]=0;
while(n){
s.push(n%p);n/=p;
}
while(!s.empty()) a[++a[0]]=s.top(),s.pop();
int tmp=0;
while(m){
tmp++;
s.push(m%p);m/=p;
}
while(b[0]+tmp<a[0]) b[++b[0]]=0;//前导零的位置一定要清零
while(!s.empty()) b[++b[0]]=s.top(),s.pop();
fac[0]=1;
for(reg int i=1;i<p;i++) fac[i]=(1ll*fac[i-1]*i)%p;
g[p-1]=power(fac[p-1],p-2);
for(reg int i=p-2;i;i--) g[i]=(1ll*g[i+1]*(i+1))%p;
}
int main(){int t=read();while(t--){
n=read();m=read();p=read();
n+=m;m=n-m;
// std::memset(a,0,sizeof a);std::memset(b,0,sizeof b);
pre();
// for(reg int i=1;i<=a[0];i++) std::printf("%d ",a[i]);EN;
// for(reg int i=1;i<=b[0];i++) std::printf("%d ",b[i]);EN;
// for(reg int i=0;i<p;i++) std::printf("%d ",fac[i]);EN;
// for(reg int i=0;i<p;i++) std::printf("%d ",g[i]);EN;
LL ans=1;
// std::printf("%d %d\n",a[0],b[0]);
for(reg int i=1;i<=a[0];i++){
if(!b[i]) continue;
if(a[i]<b[i]){ans=0;break;}
if(a[i]==b[i]) continue;
ans=(1ll*ans*fac[a[i]])%p;
ans=(1ll*ans*g[b[i]])%p;
ans=(1ll*ans*g[a[i]-b[i]])%p;
}
std::printf("%lld\n",ans);
}
return 0;
}
P3807【模板】卢卡斯定理的更多相关文章
- 【洛谷P3807】(模板)卢卡斯定理
卢卡斯定理 把n写成p进制a[n]a[n-1][n-2]…a[0],把m写成p进制b[n]b[n-1][n-2]…b[0],则C(n,m)与C(a[n],b[n])*C(a[n-1],b[n-1])* ...
- 887. 求组合数 III(模板 卢卡斯定理)
a,b都非常大,但是p较小 前边两种方法都会超时的 N^2 和NlongN 可以用卢卡斯定理 P*longN*longP 定义: 代码: import java.util.Scanner ...
- 洛谷.3807.[模板]卢卡斯定理(Lucas)
题目链接 Lucas定理 日常水题...sublime和C++字体死活不同步怎么办... //想错int范围了...不要被longlong坑 //这个范围现算阶乘比预处理快得多 #include &l ...
- 【数论】卢卡斯定理模板 洛谷P3807
[数论]卢卡斯定理模板 洛谷P3807 >>>>题目 [题目] https://www.luogu.org/problemnew/show/P3807 [输入格式] 第一行一个 ...
- P3807 【模板】卢卡斯定理
P3807 [模板]卢卡斯定理 求 \(C_{m + n}^{m} \% p\) ( \(1\le n,m,p\le 10^5\) ) 错误日志: 数组开小(哇啊啊啊洼地hi阿偶我姑父阿贺佛奥UFO爱 ...
- 洛谷 P3807 【模板】卢卡斯定理
P3807 [模板]卢卡斯定理 题目背景 这是一道模板题. 题目描述 给定n,m,p(1\le n,m,p\le 10^51≤n,m,p≤105) 求 C_{n+m}^{m}\ mod\ pCn+mm ...
- 洛谷——P3807 【模板】卢卡斯定理
P3807 [模板]卢卡斯定理 洛谷智推模板题,qwq,还是太弱啦,组合数基础模板题还没做过... 给定n,m,p($1\le n,m,p\le 10^5$) 求 $C_{n+m}^{m}\ mod\ ...
- 【luogu P3807】【模板】卢卡斯定理/Lucas 定理(含 Lucas 定理证明)
[模板]卢卡斯定理/Lucas 定理 题目链接:luogu P3807 题目大意 求 C(n,n+m)%p 的值. p 保证是质数. 思路 Lucas 定理内容 对于非负整数 \(n\),\(m\), ...
- 【刷题】洛谷 P3807 【模板】卢卡斯定理
题目背景 这是一道模板题. 题目描述 给定\(n,m,p( 1\le n,m,p\le 10^5)\) 求 \(C_{n+m}^{m}\ mod\ p\) 保证 \(p\) 为prime \(C\) ...
随机推荐
- jsonpath 字典中取值
jsonpath 第三方模块 def getsign(): url="http://api.nnzhp.cn/api/user/login" data = {"usern ...
- python3(三十) Enum
""" """ __author__ = 'shaozhiqi' # 当我们需要定义常量时,一个办法是用大写变量通过整数来定义,例如月份: ...
- nginx内置高可用配置与第三方高可用模块nginx_ustream_check_mudule配置
1. nginx 第三方高可用模块 IP 备注 10.0.0.63 proxy 10.0.0.64 web1 10.0.0.65 web2 这里会讲解一些nignx常用高可用方案,以及引入第三方高可用 ...
- 分享一本Java并发编程的免费好书
最近当当的大促销又开始了,估计很多人脑子一热,又花钱囤了不少技术书吧. 在我看来大部分程序员买技术书的用途(以下排名按用途从大到小): 让领导.同事看见,你看我多爱学习: 给自己一个心理安慰,我还没废 ...
- tf.nn.sigmoid_cross_entropy_with_logits 分类
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,,labels=None,logits=None,name=None) logits和la ...
- shell map数据结构的实现
前言 Bash默认不支持二维数组,如果我们想实现map 数据结构,可以安装如下的方式来进行构造 预备知识 eval: 它是shell内建命令,用于字符串的解析.它会首先扫描命令行 ...
- [总结]RMQ问题&ST算法
目录 一.ST算法 二.ST算法の具体实现 1. 初始化 2. 求出ST表 3. 询问 三.例题 例1:P3865 [模板]ST表 例2:P2880 [USACO07JAN]平衡的阵容Balanced ...
- 你自学半年也搞不懂的go底层,看这篇。这篇讲 go的数组、切片、Maps
目录 数组 1.定义数组 2.使用数组 3.定义并赋值 4.数组的大小是类型的一部分 5.数组是值类型(当参数传递到函数中,修改不会改变原来的值) 6.数组长度 7.循环数组 8.多维数组 切片 1. ...
- shiro:入门程序(一)
SpringMVC项目 1:pom引入相关依赖 <dependencies> <!--测试依赖--> <dependency> <groupId>jun ...
- Java 使用正则表达式和IO实现爬虫以及503解决
我这边找了个小说网站: 基本套路: 第一步:获取小说每一章的url地址 第二步:获取章节url内容并使用正则表达式提取需要的内容 第三步:多线程封装,实现如下效果 最后测试. 代码: 内容获取封装: ...