同余系全家桶
作者:互联网
一.逆元
如果一个线性同余方程 \(ax \equiv 1 \pmod b\),则称 \(x\) 为 \(a \bmod b\) 的逆元,记为 \(a^{-1}\)。
使用方法
对于 \(\frac{a}{b} \bmod p\),求出 \(b \bmod p\) 的逆元,与 \(a\) 相乘并 \(\bmod p\) 得到结果。
优势:避免了分数的精度问题。
求逆元
exgcd 法
求解 \(ax \equiv 1 \pmod b\),可以变形为求解 \(ax+by =1\),使用 exgcd。
code:
点击查看代码
void exgcd(ll a, ll b, ll &x, ll &y) {
if(!b){
x=1,y=0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
}
int main() {
ll x, y;
cin>>x>>y>>p;
exgcd(a, p, x, y);
x=(x % p + p) % p;
cout<<x;
return 0;
}
快速幂法
前置知识:费马小定理。
因为 \(ax \equiv 1 \pmod b\)
所以有 \(ax \equiv a^{b-1} \pmod b\)
得 \(x \equiv a^{p-2}\),用快速幂求解。
code:
见 Lucas 代码。
二.CRT
先咕着。
三.Lucas 定理
Lucas 定理是用来求这个东西的:
\[\dbinom{n}{m} \bmod p \]其中 \(p\) 为较小质数。
其结论为:
\[\dbinom{n}{m} \bmod p = \dbinom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p \right\rfloor} \cdot \dbinom{n\bmod p}{m\bmod p} \bmod p \]因为 \(p\) 值较小,\(\binom{n\bmod p}{m\bmod p}\) 可以直接预处理 \(O(1)\) 求解。而 \(\binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p \right\rfloor}\) 可以继续用 Lucas 定理分解递归求解。
证明
首先根据定义可知:
\[\dbinom{p}{n} \bmod p=\dfrac{p!}{n! \cdot (n-p)!} \bmod p \]可以找到性质:仅当 \(n=0 \vee n=p\) 时,该式结果为 \(1\),否则为 \(0\)。
据此扩展可得:
\[\begin{align} (a+b)^p &= \sum_{n=0}^p \binom pn a^n b^{p-n}\\&\equiv \sum_{n=0}^p [n=0\vee n=p] a^n b^{p-n}\\ &\equiv (a^p +b^p) \bmod p \end{align} \]最后将其推广到二项式情况,将 \(p\) 提进来即可。
也可以参考lhx大佬的另类证明
code:
点击查看代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
ll t,n,m,p;
ll jie[100005]={1};
ll ksm(ll y,ll z,ll p){
y%=p;
ll ans=1;
for(int i=z;i;i>>=1,y=y*y%p){
if(i&1){
ans=ans*y%p;
}
}
return ans;
}
ll C(ll n,ll m){
if(m>n) return 0;
return ((jie[n]*ksm(jie[m],p-2,p))%p*ksm(jie[n-m],p-2,p)%p);
}
ll lucas(ll n,ll m){
if(m==0) return 1;
return lucas(n/p,m/p)*C(n%p,m%p)%p;
}
int main(){
cin>>t;
while(t--){
cin>>n>>m>>p;
jie[0]=1;
for(int i=1;i<=p;i++){
jie[i]=jie[i-1]*i%p;
}
cout<<lucas(n+m,n)<<endl;
}
return 0;
}
我才不会告诉你这东西其实只有结论需要记略略略
例题: [SHOI2015]超能粒子炮·改
题意:求
\[\sum_{i=0}^k\dbinom{n}{i} \bmod p \]且\(p=2333\)
思路:
首先用 Lucas 变形可得:
\[\sum_{i=0}^k \cdot \dbinom{\left\lfloor n/p \right\rfloor}{\left\lfloor i/p \right\rfloor} \cdot \dbinom{n\bmod p}{i\bmod p} \bmod p \]我草,剩下的不会了。
四.扩展 Lucas 定理(exLucas)
恶心东西。不想写。
标签:lfloor,return,dbinom,bmod,全家,同余系,ll,equiv 来源: https://www.cnblogs.com/victoryang-not-found/p/16603501.html