【科技】扩展Lucas随想
扩展Lucas解决的还是一个很Simple的问题:
求:$C_{n}^{m} \; mod \; p$。
其中$n,m$都会比较大,而$p$不是很大,而且不一定是质数。
扩展Lucas可以说和Lucas本身并没有什么关系,重要的是中国剩余定理。扩展Lucas这个算法中教会我们的除了算组合数,还有在模数不是质数的时候,往往可以用$CRT$来合并答案。
将原模数质因数分解:$P = \prod\limits_{i = 1}^{m} p_{i}^{k_{i}}$。
列出$m$个同余方程,第$i$个形如:$C_{n}^{m} \; \equiv a_{i} (mod \; p_{i}^{k_{i}})$。
由于$m$个方程中模数互质,则$CRT$后就是原答案。
现在来对于某个方程求解$a_{i}$是多少,即$C_{n}^{m} \; mod \; p^{k}$的答案。
把组合数转化成阶乘:$\frac{n!}{m!(n - m)!}$,我们先求一个阶乘在$mod \; p^{k}$下的值,设这个函数为$Fac(n)$。
常规的对于式子下方的阶乘我们需要求逆元,而阶乘中存在$p$的倍数,这意味可能不与$p^{k}$互质。为了解决这个问题,我们将有关$p$单独考虑,于是一个算阶乘的函数将包括两部分:
- 首先考虑所有$p$的倍数,总共有$\lfloor \frac{n}{p} \rfloor$个,将$p$提出来,这$\lfloor \frac{n}{p} \rfloor$个数又成为一个阶乘的形式,递归即可,总层数不会超过$log$。这部分的答案就是$p^{\lfloor \frac{n}{p} \rfloor} * Fac(\lfloor \frac{n}{p} \rfloor)$。
- 剩下的数都将与$p^{k}$互质。我们考虑以$p^{k}$分块,我们可以证明每段$p^{k}$中所有不是$p$的倍数的数的乘积在模$p^{k}$意义下是相同的。具体原因在于$i + p^{k} \equiv i (mod \; p^{k})$。通过暴力计算,这部分的复杂度就是$O(p^{k})$的。
接下来就没有什么问题了,用扩展欧几里得求逆元,有关$p$的幂次在除法时指数相减就行了。
#include <cstdio> typedef long long LL; int P; int Pow(int x, LL b, int p) {
static int re;
for (re = ; b; b >>= , x = (LL) x * x % p)
if (b & ) re = (LL) re * x % p;
return re;
}
int Ex_gcd(int a, int b, int &x, int &y) {
if (b == ) return x = , y = , a;
int gcd = Ex_gcd(b, a % b, y, x);
y -= a / b * x;
return gcd;
}
int Inv(int a, int p) {
static int x, y;
int gcd = Ex_gcd(a, p, x, y);
if (gcd != ) throw;
return (x % p + p) % p;
} int Fac(LL n, int p, int pk) {
if (n == ) return ;
int re = ;
for (int i = ; i <= pk; ++i)
if (i % p != ) re = (LL) re * i % pk;
re = Pow(re, n / pk, pk);
for (int i = ; i <= n % pk; ++i)
if (i % p != ) re = (LL) re * i % pk;
return (LL) re * Fac(n / p, p, pk) % pk;
} int Crt(LL n, LL m, int p, int pk) {
int fn = Fac(n, p, pk), fm = Fac(m, p, pk), fnm = Fac(n - m, p, pk);
int cp = ;
for (LL i = n; i; i /= p) cp += i / p;
for (LL i = m; i; i /= p) cp -= i / p;
for (LL i = n - m; i; i /= p) cp -= i / p;
int a = (LL) fn * Inv(fm, pk) % pk * Inv(fnm, pk) % pk * Pow(p, cp, pk) % pk;
return (LL) a * (P / pk) % P * Inv(P / pk, pk) % P;
} int Lucas(LL n, LL m, int p) {
int re = , x = p;
for (int i = ; i <= p; ++i) {
if (x % i != ) continue;
int pk = ;
while (x % i == ) pk *= i, x /= i;
re = (re + Crt(n, m, i, pk)) % p;
}
return re;
} int main() {
LL n, m;
scanf("%lld%lld%d", &n, &m, &P);
printf("%d\n", Lucas(n, m, P)); return ;
}
【科技】扩展Lucas随想的更多相关文章
- bzoj 4830: [Hnoi2017]抛硬币 [范德蒙德卷积 扩展lucas]
4830: [Hnoi2017]抛硬币 题意:A投a次硬币,B投b次硬币,a比b正面朝上次数多的方案数,模\(10^k\). \(b \le a \le b+10000 \le 10^{15}, k ...
- 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 ...
- BZOJ_2142_礼物_扩展lucas+组合数取模+CRT
BZOJ_2142_礼物_扩展lucas+组合数取模 Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同 ...
- 扩展CRT +扩展LUCAS
再次感谢zyf2000超强的讲解. 扩展CRT其实就是爆推式子,然后一路合并,只是最后一个式子上我有点小疑惑,但整体还算好理解. #include<iostream> #include&l ...
- BZOJ3129 SDOI2013方程(容斥原理+扩展lucas)
没有限制的话算一个组合数就好了.对于不小于某个数的限制可以直接减掉,而不大于某个数的限制很容易想到容斥,枚举哪些超过限制即可. 一般情况下n.m.p都是1e9级别的组合数没办法算.不过可以发现模数已经 ...
- Codeforces.100633J.Ceizenpok's formula(扩展Lucas)
题目链接 ->扩展Lucas //求C_n^k%m #include <cstdio> typedef long long LL; LL FP(LL x,LL k,LL p) { L ...
- P2467 [SDOI2010]地精部落 (dp+组合数)【扩展Lucas好难不会】
题目链接:传送门 题目: 题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为N的山脉H可分为从左到右的N段,每段有一个独一无二的高度Hi,其 ...
- 【learning】 扩展lucas定理
首先说下啥是lucas定理: $\binom n m \equiv \binom {n\%P} {m\%P} \times \binom{n/P}{m/P} \pmod P$ 借助这个定理,求$\bi ...
- BZOJ4830 [Hnoi2017]抛硬币 【扩展Lucas】
题目链接 BZOJ4830 题解 当\(a = b\)时,我们把他们投掷硬币的结果表示成二进制,发现,当\(A\)输给\(B\)时,将二进制反转一下\(A\)就赢了\(B\) 还要除去平局的情况,最后 ...
随机推荐
- 011 --Mysql中特定查询
1.优化COUNT()查询 COUNT()可能是被大家误解最多的函数了,它有两种不同的作用,其一是统计某个列值的数量,其二是统计行数.统计列值时,要求列值是非空的,它不会统计NULL.如果确认括号中的 ...
- Azure-如何排查应用程序网关返回 HTTP Code 502 或客户端得到应用程序网关响应慢的问题(二)
问题描述 经过如何排查应用程序网关返回 HTTP Code 502 或客户端得到应用程序网关响应慢的问题(一)中的排查步骤,可以判断出是由于 Web 服务器自身问题导致的响应异常. 那么可以在 IIS ...
- 后端程序员必备的Linux基础知识
我自己总结的Java学习的系统知识点以及面试问题,目前已经开源,会一直完善下去,欢迎建议和指导欢迎Star: https://github.com/Snailclimb/Java-Guide > ...
- psp报告
1.读材料回答问题 (1)回想一下你曾经对计算机专业的畅想.当初你是如何做出选择计算机专业的决定的?你认为过去接触到的课程是否符合你对计算机专业的期待,为什么?你觉得计算机是你喜欢的领域吗,它是你擅长 ...
- (第九周)Beta-1阶段成员贡献分
项目名:食物链教学工具 组名:奋斗吧兄弟 组长:黄兴 组员:李俞寰.杜桥.栾骄阳.王东涵 个人贡献分=基础分+表现分 基础分=5*5*0.5/5=2.5 成员得分如下: 成员 基础分 表现分 个人贡献 ...
- Daily Srum 10.21
到目前为止,我们组处在学习阶段,很多知识点都还不太清楚,所以现在我们还在看相关书籍和博客,任务. 而我们此间主要是在阅读一些材料: 陈谋一直在看学长的代码,其中C#的很多方式我都不太明白(尽管和Jav ...
- 第三周vim入门学习2
一.vim重复命令 1.重复执行上次命令 在普通模式下.(小数点)表示重复上一次的命令操作 拷贝测试文件到本地目录 $ cp /etc/protocols . 打开文件进行编辑 $ vim proto ...
- 【请仔细核对Git地址】关于代码量排名的说明
1.截至2017年3月14日,1623班级代码统计情况如下: 2.代码量排名是基于码云的git地址统计的,请大家仔细核对以下个人地址,如有问题请及时联系我. 20162301 20162302 201 ...
- 20162314 《Program Design & Data Structures》Learning Summary Of The Fifth Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Fifth Week ...
- WebGL学习笔记二
前一章就是第二章主要学的是通过WebGL实现先是在webGL内赋值,但是不实用后来通过定义attribute和uniform存储限定符来将javascript中的数据传到webGL中,大致的流程是1. ...