T^TOJ 组合数取模
乘法逆元知识
组合计数-插板法
类型0:n,m<=1000 直接暴力预处理杨辉三角,预处理复杂度O(n*n) 公式:C(n,m)=C(n,n-m)=C(n-1,m-1)+C(n-1,m)
类型1:n,m<=1e6 且模数p是质数。 O(n)预处理 阶乘fac[i]和阶乘的逆ifac即可。然后 C(n,m)=fac[n]*ifac[m]*ifac[n-m]
预处理复杂度O(n),查询O(1)。HDU6333 Problem B. Harvest of Apples 莫队算法+逆元
类型2:n,m <=1e18 且模数p为质数,且p<=1e5,用Lucas定理,展开成多个组合数的乘积。
单次查询复杂度O(p*log(n)/log(p)) HDU3037 Saving Beans Lucas 定理+逆元
类型3:n,m,p <=1e18 且模数p为非质数,用Lucas定理+中国剩余定理
单次查询复杂度O(VY*p*log(n)/lop(p))V,Y为p的质因子个数和幂次 HDU5446 Unknown Treasur Lucas+中国剩余定理
类型4:n<=1e9,m<=1e5, p<=1e9且为质数,用逆元暴力计算C(n,m)=n*(n-1)*(n-2)*……*(n-m+1)/(1*2*……*m)
算法复杂度O(m)
类型5: n,m<=1e5,mod非质数, 对阶乘分解质因数,然后跑快速幂,算法复杂度O(n)
#include
using namespace std;
const int MAX=1e6+1;
const long long MOD=1e9+7;
int prim[MAX],fac[MAX];
void prime()
{
memset(prim,0,sizeof(prim));
for(int i=2;i>=1;
}
return b;
}
long long C(int a,int b)
{
factor(a,b);
long long c=1;
for(int i=1;i
附 大数质因分解
#include
using namespace std;
const int MAX=1e5+1;
int prim[MAX],fac[MAX][2],facnt;
void prime()
{
memset(prim,0,sizeof(prim));
for(int i=2;i