CRT, lucas及其扩展形式

exgcd

int exgcd(int a, int b, int &x, int &y) {
if (b == 0) return a, x = 1, y = 0;
int y = exgcd(b, a % b, x, y), t;
t = x, x = y, y = t - a / b * y;
}

证明:

gcd的过程中, 假设我们已经求出了\(b * x + (a~\%~b) * y = gcd(a, b)\)推导到\(a*x + b*y = gcd(a, b)\)的形式

\[b * x + (a - \frac ab*b) y = \gcd(a, b)\\
a * y + b * (x - \frac ab * y) = \gcd(a, b)
\]

中国剩余定理(CRT)

问题: 求最小整数解x, 其中\(P_1,P_2\cdots P_n\)互素

\[\left\{\begin{matrix}
x \equiv a_1 \mod P_1\\
x \equiv a_2 \mod P_2\\
\vdots \\
x \equiv a_n \mod P_n\\
\end{matrix}\right.
\]

设\(M = \Pi^n_{i=1} P_i~~~ M_i=\frac M{P_i}~~~M_i^{i-1}\)为\(modM_i\)意义下的逆元 那么

\[X = (\sum_{i=1}^na_iM_iM_i^{-1}) \mod M
\]

扩展中国剩余定理(exCRT)

问题同中国剩余定理但各模数P不互质

假设已经求出前\(k-1\)个方程组成的同余方程组的一个解为\(x\), 且有 \(M=LCM_{i-1}^{k-1}P_i\), 则满足前k个方程的解为\(x + t * M\)

加入第k个方程得\(x + t * M = a_i \mod P_k\)

即 \(t*M=a_i-x \mod P_i\)

\(exgcd\)求解即可, 同时可以判是否有解

Lucas定理

解决的问题, P是质数且不大, 而n, m可以很大

\[{n \choose m} \mod P
\]

证明咕咕咕, 其实没啥用

\[{n\choose m} \mod P = {n\mod P \choose m\mod P} * { \frac np \choose \frac mp}
\]

其实可以理解为转化为p进制下

ll C(int n,int m) {
if (m > n) return 0;
return jie[n] * fpw(jie[m], P-2) % P * fpw(jie[n-m], P-2) % P;
} ll lau(ll x, ll y) {
if (!y) return 1;
return C(x % P, y % P) * lau(x / P, y / P) % P;
}

exLucas定理

这个比较有用, 不要求P是质数了

设\(P= \prod p_i^k\), 如果求出了\(\binom{n}{m}\bmod{p_i^{k_i}}\) 就可以利用CRT合并答案了

\[{n \choose m}= \frac{n!}{(n−m)!m!}
\]

把p都提取出来, 可以先计算上面有多少p, 下面有多少p

然后考虑其他的数, 即求\(K!\mod P\), 发现在模\(p^k\)的时候有循环节, 因为\(p^k+i \equiv p^k\)

所以对于与p互质的数直接暴力扫描一个\(p^k\)然后快速幂即可

对与不与p互质的数, 去除所有p后, 仍会有其他因子, 不妨递归解决子问题, 即先提取出一个p来, p的倍数为\(1p, 2p, 3p \cdots \frac npp\) ,都去掉一个p然后相乘等于\(\frac np!\) , 递归下去就好喽

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#define ll long long
using namespace std;
ll m, n, p; ll exgcd(ll a, ll b, ll &x, ll &y) {
if (!b) return x = 1, y = 0, a;
ll gcd = exgcd(b, a % b, x, y), t;
t = x, x = y, y = t - a / b * y;
return gcd;
} ll inline inv(ll n, ll mod) {
ll x, y; exgcd(n, mod, x, y);
return (x % mod + mod) % mod;
} ll fpw(ll x, ll mi, ll mod) {
ll res = 1;
while (mi) {
if (mi & 1) res = res * x % mod;
mi >>= 1;
x = x * x % mod;
}
return res;
} ll fac(ll n, ll pi, ll pk) {
if (!n) return 1;
ll res = 1;
for (ll i = 2;i <= pk; i++)
if (i % pi) res = res * i % pk;
res = fpw(res, n / pk, pk);
for (ll i = 2;i <= n % pk; i++)
if (i % pi) res = res * i % pk;
return res * fac(n / pi, pi, pk) % pk;
} inline ll ptime(ll x, ll pi) {
ll res = 0;
for (;x ; x /= pi) res += x / pi;
return res;
} ll C(ll n, ll m, ll pi, ll pk) {
ll up = fac(n, pi, pk), d1 = fac(m, pi, pk), d2 = fac(n - m, pi, pk);
ll k = ptime(n, pi) - ptime(n-m, pi) - ptime(m, pi);
return up * inv(d1, pk) % pk * inv(d2, pk) % pk * fpw(pi, k, pk) % pk;
} ll CRT(ll b, ll mod) {
return b * inv(p / mod, mod) % p * (p / mod) % p;
} inline ll exlucus(ll n, ll m) {
ll res = 0, tmp = p, pk;
ll lim = sqrt(p);
for (int i = 2;i <= lim; i++) {
if (tmp % i == 0) {
pk = 1;
while(tmp % i == 0) pk *= i, tmp /= i;
res = (res + CRT(C(n, m, i, pk), pk)) % p;
// cout << tt << endl;
}
}
if (tmp > 1) res = (res + CRT(C(n, m, tmp, tmp), tmp)) % p;
return res;
} int main() {
cin >> n >> m >> p;
printf ("%lld\n", exlucus(n, m));
return 0;
}

CRT, lucas及其扩展形式的更多相关文章

  1. codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula 扩展Lucas定理 扩展CRT

    默默敲了一个下午,终于过了, 题目传送门 扩展Lucas是什么,就是对于模数p,p不是质数,但是不大,如果是1e9这种大数,可能没办法, 对于1000000之内的数是可以轻松解决的. 题解传送门 代码 ...

  2. HDU 5446——Unknown Treasure——————【CRT+lucas+exgcd+快速乘+递推求逆元】

    Each test case starts with three integers n,m,k(1≤m≤n≤1018,1≤k≤10) on a line where k is the number o ...

  3. luogu 2480 古代猪文 数论合集(CRT+Lucas+qpow+逆元)

    一句话题意:G 的 sigma d|n  C(n d) 次幂  mod 999911659 (我好辣鸡呀还是不会mathjax) 分析: 1.利用欧拉定理简化模运算 ,将上方幂设为x,则x=原式mod ...

  4. 扩展Lucas定理 扩展Lucas板子

    题意概述:多组询问,给出N,K,M,要求回答C(N,K)%M,1<=N<=10^18,1<=K<=N,2<=M<=10^6 分析: 模数不为质数只能用扩展Lucas ...

  5. 欧几里得(辗转相除gcd)、扩欧(exgcd)、中国剩余定理(crt)、扩展中国剩余定理(excrt)简要介绍

    1.欧几里得算法(辗转相除法) 直接上gcd和lcm代码. int gcd(int x,int y){ ?x:gcd(y,x%y); } int lcm(int x,int y){ return x* ...

  6. 中国剩余定理(crt)和扩展中国剩余定理(excrt)

    数论守门员二号 =.= 中国剩余定理: 1.一次同余方程组: 一次同余方程组是指形如x≡ai(mod mi) (i=1,2,…,k)的同余方程构成的组 中国剩余定理的主要用途是解一次同余方程组,其中m ...

  7. [NOIP模拟测试7]visit 题解(组合数学+CRT+Lucas定理)

    Orz 因为有T的限制,所以不难搞出来一个$O(T^3)$的暴力dp 但我没试 据说有30分? 正解的话显然是组合数学啦 首先$n,m$可能为负,但这并没有影响, 我们可以都把它搞成正的 即都看作向右 ...

  8. [xdoj1227]Godv的数列(crt+lucas)

    解题关键:1001=7*11*13,模数非常小,直接暴力lucas.递归次数几乎为很小的常数.最后用中国剩余定理组合一下即可. 模数很小时,一定记住lucas定理的作用 http://acm.xidi ...

  9. HDU 5446 CRT+Lucas+快速乘

    Unknown Treasure Problem Description On the way to the next secret treasure hiding place, the mathem ...

随机推荐

  1. TypeError: react__WEBPACK_IMPORTED_MODULE_2___default.a.createClass is not a function

    在看阮一峰的react入门的时候,写到一段代码,但是写完就报错了,经过多方查找,终于解决掉了 错误描述: 解决方法: 将React.createClass换成React.Component, 但是不知 ...

  2. 《Machine Learning in Action》—— Taoye给你讲讲决策树到底是支什么“鬼”

    <Machine Learning in Action>-- Taoye给你讲讲决策树到底是支什么"鬼" 前面我们已经详细讲解了线性SVM以及SMO的初步优化过程,具体 ...

  3. Kafka高性能揭秘:sequence IO、PageCache、SendFile的应用详解

    大家都知道Kafka是将数据存储于磁盘的,而磁盘读写性能往往很差,但Kafka官方测试其数据读写速率能达到600M/s,那么为什么Kafka性能会这么高呢? 首先producer往broker发送消息 ...

  4. Java编发编程 - 线程池的认识(二)

    核心线程池的内部实现 依然参考 JDK 对线程池的支持,各个接口.相关类之间的关系:  (1)对于Executors中几个创建线程池方法底层实现: // 创建固定线程数量的线程池 public sta ...

  5. php(tp5)实现分页效果

    public function admin(){ if(request()->isPost()){ //获取第二页的数据传current = 2过来即可 $post['origin'] = in ...

  6. 痞子衡嵌入式:揭秘i.MXRT600的ISP模式下用J-Link连接后PC总是停在0x1c04a的原因(Debug Mailbox)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT600中的Debug Mailbox实现对JLink调试的影响. 事情缘起痞子衡的同事 - 喜欢打破砂锅问到底的Kerry小 ...

  7. Mac插件太多太乱怎么办?CleanMyMac直接帮你搞定!

    电脑应用插件在一定程度上便利了大家的生活,保障了用户的使用安全,比如Flash插件.浏览器翻译插件.银行安全登录插件等等.但是许多的插件并不能定位安装的位置,同时部分插件,大部分时候都是只使用一次的, ...

  8. Luogu P2656 采蘑菇

    尽管是缩点的习题,思路也是在看了题解后才明白的. 首先,每个强连通分量内的点都是一定互通的,也就是可以完全把这里面的边都跑满,摘掉所有能摘的蘑菇.那么,考虑给每一个强连通分量化为的新点一个点权,代表摘 ...

  9. 【震惊】手把手教你用python做绘图工具(一)

    在这篇博客里将为你介绍如何通过numpy和cv2进行结和去创建画布,包括空白画布.白色画布和彩色画布.创建画布是制作绘图工具的前提,有了画布我们就可以在画布上尽情的挥洒自己的艺术细胞. 还在为如何去绘 ...

  10. 生僻的mysql

    1.show table status like 'user' 2.alter table mytableEngine=InnoDB 需要执行很长时间,mysql会按行将数据从原表复制到一张新的表中, ...