2023.2.26【模板】扩展Lucas定理

题目概述

求\(\binom {n}{m} mod\) \(p\) 的值,不保证\(p\)为质数

算法流程

(扩展和普通算法毫无关系)

由于\(p\)不是质数,我们考虑[SDOI2010]古代猪文 - 洛谷中的处理方法:将\(p\)质因数分解得:

\[p = {p_1}^{c_1}{p_2}^{c_2}{p_3}^{c_3}....{p_k}^{c_k}
\]

所以我们考虑计算$\binom nm mod $ \({p_i}^{c_i}\)的值,再用CRT合并即可

展开上式:

\[\frac {n!}{m!(n - m)!} mod\ {p_i}^{c_i}
\]

我们发现由于\(m!(n - m)!\)中可能含有因数p,我们无法求出\(m!(n - m)!\)模\({p_i}^{c_i}\)意义下的逆元,所以我们考虑除去三个数中所有的p因子,假设\(p^x | n!\)且\(p^{x+1} \nmid n!\),即x是\(n!\)中p因子的个数(对于\(m!\)和\((n - m)!\)同理)

\[\frac {\frac{n!}{p^x}}{\frac{m!}{p^y}\frac{(n - m)!}{p^z}}p^{x - y - z}\ mod\ {p_i}^{c_i}
\]

由于\(\frac{n!}{p^x}、\frac{m!}{p^y}、\frac{(n - m)!}{p^z}\)三式同构,我们考虑计算其中一个式子(以下用\(p\)替换\(p_i\))

\[\frac {n!}{p^x}\ mod \ {p}^{c_i}
\]

展开为

\[\frac {1*2*3*...*n}{p^x}\ mod \ {p}^{c_i}
\]

提出p的倍数

\[\frac {(p * 2p * 3p * .. * \lfloor {\frac np} \rfloor p) * \Pi_{i = 1;i \not\equiv 0}^{n}}{p^x}\ mod\ {p}^{c_i}
\]

\[\frac {\lfloor {\frac np} \rfloor! * p^{\lfloor \frac np \rfloor} * \Pi_{i = 1;i \not\equiv 0}^{n}}{p^x}\ mod\ {p}^{c_i}
\]

如果暴力计算\(\Pi_{i = 1;i \not\equiv 0}^{n}\)复杂度过高,不难发现其有一个循环节,即每过p个数就会少乘上第p个数,又因为\({p_i}^{c_i}+ r \equiv r\ mod\ {p_i}^{c_i}\),所以我们以\({p_i}^{c_i}\)作为这个循环节

\[\frac {\lfloor {\frac np} \rfloor! * p^{\lfloor \frac np \rfloor} * {[\Pi_{i = 1;i \not\equiv 0}^{p^{c_i}}]}^{\lfloor\frac {n}{p^{c_i}}\rfloor}\Pi_{i = {p^{c_i}}\lfloor\frac{n}{p^{c_i}}\rfloor;i \not\equiv 0}^{n}}{p^x}\ mod\ {p}^{c_i}
\]

对于\(\Pi_{i = 1;i \not\equiv 0}^{p^{c_i}}\)和\(\Pi_{i = {p^{c_i}}\lfloor\frac{n}{p^{c_i}}\rfloor;i \not\equiv 0}^{n}\),暴力计算即可

不管\(x\)取何值,最终p因子都会消除,所以计算时去掉\(p^{\lfloor \frac np \rfloor}\)

因为\(\lfloor \frac np \rfloor!\)中可能含有p因子,所以我们将其进行递归:

设\(f(n) = \frac {n!}{p^x}\ mod \ {p}^{c_i}\),则:

\[f(n) = {f(\lfloor {\frac np} \rfloor) * {[\Pi_{i = 1;i \not\equiv 0}^{p^{c_i}}]}^{\lfloor\frac {n}{p^{c_i}}\rfloor}\Pi_{i = {p^{c_i}}\lfloor\frac{n}{p^{c_i}}\rfloor;i \not\equiv 0}^{n}}\ mod\ {p}^{c_i}
\]

根据此式递推即可,时间复杂度为\(O(log_pn)\),不会证明qwq

对于外面的\(p^{x - y - z}\),只要求出\(x、y、z\)的值就可以计算了

观察以上函数可知,每次在\(f(n)\)这一层就会去掉\(\lfloor \frac np \rfloor\)个p因子

定义\(g(n)\)为\(n!\)中p因子的个数,则:

\[g(n) = g(\lfloor \frac np \rfloor) + \lfloor \frac np \rfloor
\]

此结论对于其他题目也同样有效

所以原始式子就转化成了

\[\frac {f(n)}{f(m)f(n - m)} * p^{g(n) - g(m) - g(n - m)} \ mod \ p^{c_i}
\]

因为去掉了p因子,所以\(f(m)\)和\(f(n - m)\)与\(p^{c_i}\)互质,可以求逆元

因为\(p^{c_i}\)不是质数,不能直接用费马小定理计算,所以我们采用\(exgcd\)求逆元

最后进行CRT合并答案

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll res[101],d[101],zs[101],tot = 0,M[101];
inline ll g(ll n,ll p)
{
if(n == 0) return 0;
return g(n / p,p) + n / p;
}
inline ll ksm(ll base,ll pts,ll mod)
{
ll ret = 1;
for(;pts > 0;pts >>= 1,base = base * base % mod)
if(pts & 1)
ret = ret * base % mod;
return ret;
}
inline ll F(ll n,ll p,ll k)
{
if(n == 0) return 1;
ll P = ksm(p,k,1e18 + 1);
ll mul = 1;
for(ll i = 1;i <= P;i++)
if(i % p)
mul = mul * i % P;
mul = ksm(mul,n / P,P);
for(ll i = P * (n / P);i <= n;i++)
if(i % p)
mul = mul * (i % P) % P;
return F(n / p,p,k) * mul % P;
}
inline void exgcd(ll a,ll b,ll &x,ll &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
ll tmp;
exgcd(b,a % b,x,y);
tmp = y;
y = x - (a / b) * y;
x = tmp;
}
inline ll exlucas(ll n,ll m,ll p)
{
ll tmp = p;
for(ll i = 2;i <= sqrt(p);i++)
{
if(tmp % i == 0)
{
++tot;
d[tot] = i;
while(tmp % i == 0)
{
tmp /= i;
++zs[tot];
}
}
}
if(tmp != 1)
{
++tot;
d[tot] = tmp;
zs[tot] = 1;
}
for(int i = 1;i <= tot;i++)
{
ll P = ksm(d[i],zs[i],1e18 + 1);
ll inv1,inv2,yy;
exgcd(F(m,d[i],zs[i]),P,inv1,yy);
exgcd(F(n - m,d[i],zs[i]),P,inv2,yy);
inv1 = (inv1 % P + P) % P;
inv2 = (inv2 % P + P) % P;
res[i] = F(n,d[i],zs[i]) * inv1 % P * inv2 % P * ksm(d[i],g(n,d[i]) - g(m,d[i]) - g(n - m,d[i]),P) % P;
M[i] = P;
}
ll ans = 0;
for(int i = 1;i <= tot;i++)
{
ll inv,yy;
exgcd(p / M[i],M[i],inv,yy);
inv = (inv % M[i] + M[i]) % M[i];
ans = (ans + res[i] * (p / M[i]) % p * inv % p) % p;
}
return ans;
}
int main()
{
ll n,m,p;
cin>>n>>m>>p;
cout<<exlucas(n,m,p);
return 0;
}

2023.2.26【模板】扩展Lucas定理的更多相关文章

  1. 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 ...

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

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

  3. 【learning】 扩展lucas定理

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

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

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

  5. Lucas定理和扩展Lucas定理

    1.Lucas定理 首先给出式子:\(C_n^m\%p = C_{\lfloor\frac{n}{p}\rfloor}^{\lfloor\frac{m}{p}\rfloor} * C_{n\%p}^{ ...

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

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

  7. [笔记] 扩展Lucas定理

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

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

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

  9. BZOJ3129/洛谷P3301方程(SDOI2013)容斥原理+扩展Lucas定理

    题意:给定方程x1+x2+....xn=m,每个x是正整数.但是对前n1个数做了限制x1<=a1,x2<=a2...xn1<=an1,同时对第n1+1到n1+n2个数也做了限制xn1 ...

  10. 扩展Lucas定理

    (1)Lucas定理:p为素数,则有: (2)证明: n=(ak...a2,a1,a0)p = (ak...a2,a1)p*p + a0 =  [n/p]*p+a0,m=[m/p]*p+b0其次,我们 ...

随机推荐

  1. js-day05-对象

    为什么要学习对象 没有对象时,保存网站用户信息时不方便,很难区别 对象是什么 1.对象是一种数据类型 2.无序的数据集合 对象有什么特点 1.无序的数据的集合 2.可以详细的描述某个事物' 对象使用 ...

  2. JavaEE Day08 HTML&CSS

    今日内容 HTML标签:表单标签 CSS:页面样式控制,美化页面,完成页面布局 一.表单标签 1.概述 用于采集用户输入数据的,如输入的用户名和密码,用于与服务器进行交互 使用from标签  form ...

  3. 【每日一题】【集合增删】2022年1月13日-NC41 最长无重复子数组-220113/220122

    描述 给定一个长度为n的数组arr,返回arr的最长无重复元素子数组的长度,无重复指的是所有数字都不相同. 子数组是连续的,比如[1,3,5,7,9]的子数组有[1,3],[3,5,7]等等,但是[1 ...

  4. 1.4 Apache Hadoop完全分布式集群搭建-hadoop-最全最完整的保姆级的java大数据学习资料

    目录 1.4 Apache Hadoop 完全分布式集群搭建 1.4.1 虚拟机环境准备 1.4.2 集群规划 1.4.3 安装Hadoop 1.4.3.1 集群配置 1.4.3.1.1 HDFS集群 ...

  5. filter: hue-rotate() 制作炫酷的文字效果

    主要用到属性有: filter 滤镜的 hue-rotate 色调旋转, text-shadow 文字阴影, transform 的 scale缩放, transition 过渡属性, animati ...

  6. 使用 System.Text.Json 时,如何处理 Dictionary 中 Key 为自定义类型的问题

    在使用 System.Text.Json 进行 JSON 序列化和反序列化操作时,我们会遇到一个问题:如何处理字典中的 Key 为自定义类型的问题. 背景说明 例如,我们有如下代码:   // 定义一 ...

  7. vue中单独封装elementui中的Dialog弹框组件

    一.在components文件中新建 弹框组件 <template> <div> <el-dialog title="提示" :visible.syn ...

  8. 学会了selenium 模拟鼠标操作,你就可以偷懒点点点了

    前言 我们在做 Web 自动化的时候,有时候页面的元素不需要我们点击,值需要把鼠标移动上去就能展示各种信息. 这个时候我们可以通过操作鼠标来实现,接下来我们来讲一下使用 selenium 做 Web ...

  9. JUC源码学习笔记7——FutureTask源码解析,人生亦如是,run起来才有结果

    系列文章目录和关于我 一丶我们在哪里会使用到FutureTask 基本上工作中和Future接口 打交道比较多,比如线程池ThreadPoolExecutor#sumbit方法,返回值就是一个Futu ...

  10. java下载网络文件的N种方式

    java下载网络文件的N种方式 通过java api下载网络文件的方法有很多,主要方式有以下几种: 1.使用 common-io库下载文件,需要引入commons-io-2.6.jar public ...