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\) ...
随机推荐
- uni-app商城项目(01)
1.项目准备: 1.新建项目,清理项目结构 2.完成项目初始化配置. 2.项目开始阶段: 1.完成tabBar配置,新建需要的页面 2.在 '/utis'封装需要的发送请求api,有利于功能的实现. ...
- Java第十五天,泛型
一.定义 泛型是一种未知的数据类型,即当我们不知道该使用哪种数据类型的时候,可以使用泛型. 泛型的本质是为了 参数化 类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型) ...
- C语言实现双向链表
目前我们所学到的链表,无论是动态链表还是静态链表,表中各节点中都只包含一个指针(游标),且都统一指向直接后继节点,通常称这类链表为单向链表(或单链表). 虽然使用单链表能 100% 解决逻辑关系为 & ...
- lr组织架构模式
基本模式:默认目录由三部分组成 Vuser_int Action,…… Vuser_end 执行时会按照这三个顺序执行(Action部分是可以循环的,也可多个action) 1.lr12录制前可以设置 ...
- Linux下删除大量文件效率对比
来自公众号:马哥Linux运维 今天我们来测试一下Linux下面删除大量文件的效率. 首先建立50万个文件 $ test for i in $(seq 1 500000);do echo text ...
- Tomcat启动过程原理详解 -- 非常的报错:涉及了2个web.xml等文件的加载流程
Tomcat启动过程原理详解 发表于: Tomcat, Web Server, 旧文存档 | 作者: 谋万世全局者 标签: Tomcat,原理,启动过程,详解 基于Java的Web 应用程序是 ser ...
- 解决Jquery中click里面包含click事件,出现重复执行的问题
出现问题的代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.o ...
- jdk动态代理:由浅入深理解mybatis底层
什么是代理 代理模式,目的就是为其他对象提供一个代理以控制对某个对象的访问,代理类为被代理者处理过滤消息,说白了就是对被代理者的方法进行增强. 看到这里,有没有感觉很熟悉?AOP,我们熟知的面向切面编 ...
- C++调用TensorFlow
在使用C++调用TensorFlow接口时出现的问题,网上没有资料,问了老师才知道的. Exception ignored in: <module 'threading' from 'E:\\t ...
- python3如何不生成pyc文件
使用-B参数 即 python3 -B test.py 设置环境变量 export PYTHONDONTWRITEBYTECODE=1 在导入的地方增加 import sys sys.dont_wri ...