lllll
\(A^m_n=\frac{n!}{(n-m)!}\)
\(C^m_n=\frac{n!}{m!(n-m)!}\)
\(C^m_n=\frac{A^m_n}{A^m_m}=C^{n-m}_n\)
\(C^m_{n+1}=C^m_n+C^{m-1}_n\)
\(C^0_n+C^1_n+C^2_n+……+C^n_n=2^n\)
逆元
我的理解就是将 \(\frac{n}{m}\)%p中的\(\frac{1}{m}\)在%p时合法化,数值记为inv[m]
所以可以用n*inv[m]%p来表示\(\frac{n}{m}\)%p
拓展欧几里得求逆元
// ax+by=1
int exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a; // a为最大公约数
}
// 注意传参及下面的计算
int ret = exgcd(b, a%b, y, x);
y -= a/b*x;
return ret;
}
// ax+by=1
int exgcd2(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1;
y = 0;
return a; // a为最大公约数
}
// 下面的x、y交换是很直观的根据推到式子来的
int ret = exgcd2(b, a%b, x, y);
int t = x;
x = y;
y = t - a/b*y;
return ret;
}
其中x的值为b%p意义下逆元
模数为素数可以用费马小定理求
费马
typedef long long ll;
ll quickpow(ll a, ll n, ll p) { //快速幂求 a^n % p
ll ans = 1;
while(n) {
if(n & 1) ans = ans * a % p;
a = a * a % p;
n >>= 1;
}
return ans;
}
ll niyuan(ll a, ll p) { //费马小定理求逆元 a^(p-2)%p
return quickpow(a, p - 2, p);
}
因为逆元n为\(\frac{1}{n}\)%p下的合法状态,所以可以利用\(\frac{1}{n!}=\frac{1}{(n+1)!}*(n+1)\)来对应求阶乘逆元
线性求阶乘逆元
inv[n]=qpow(fact[n],p-2,p);
for(int i=n-1;i>=1;i--){
inv[i]=inv[i+1]*(i+1)%p;
}
线性求逆元
// 因为 1<i<p,所以 p/i 一定小于 p
ny[1] = 1;
for (int i = 2; i < p; ++i) {
ny[i] = (long long)(p - p / i) * ny[p % i] % p; // 注意最后的模 p 不要忘记
}
快读
inline int read(){
int x=0,f=1;
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
return x*f;
}
快输
void write(int out){
if(out<0) putchar('-'),out=-out;
if(out>9) write(out/10);
putchar(out%10+'0');
return;
}
(从某人那偷来的)