需要用到的知识
-
组合数
其中:C(m,n) = n! / (m!*(n-m)!) //默认n>m
-
判断一个数是否是奇数:if( n&1 )
其中:n为奇数 // 奇数2进制末位为1,1与1进行与运算结果为1; -
拓展:
n>>=1 右移1位 除以2;n<<=1 左移1位 乘以2;
-
费马小定理
费马小定理:假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p)
所以a*a^(p-2)≡1(mod p)
得出:a^(p-2)就是a的乘法逆元
利用快速幂可以计算出a^(p-2) -
快速幂
ll quick_pow(ll x,ll n,ll mod)
{
ll res=1;
while( n ){
if(n & 1) {
res = res * x % mod;
}
x = x * x % mod;
n >>= 1;
}
return res;
}
- 费马小定理和快速幂求解组合数
#include <bits/stdc++.h>
using namespace std;
#define rep(x,l,u) for(ll x=l;x<u;x++)
#define rrep(x,l,u) for(ll x=l;x<=u;x++)
const ll maxn = 150005;
const ll p = 998244353
typedef long long ll;
ll fac[2*maxn+5];
int main()
{
ll quick_pow(ll x,ll n){
ll res = 1;
while(n){
if( n&1 ) res = res * x % p;
x = x * x % p;
n >>= 1;
}
return res;
}
void s(){
fac[0] = 1;
rrep(i,0,n) fac[i] = fac[i-1] * i % p; //注意不能少mod
return fac[n] * quick_pow(fac[m],p-2) % p * quick_pow(fac[n-m],p-2) % p;
}
return 0;
}