使用前先build(),之后可以直接调用C()求组合数,其中涉及逆元知识,自行移步。
const int SIZE = 2001; LL fac[SIZE],inv[SIZE],p; LL mypow(LL x,LL y){ LL res=1; while(y){ if(y&1)res=res*x%p; y>>=1; x=x*x%p; } return res; } LL C(int x,int y){ if(y<0||y>x)return 0; return fac[x]*inv[y]%p*inv[x-y]%p; } void build() { assert(p>=SIZE); fac[0]=1; for(int i=1;i<=SIZE;i++) fac[i]=fac[i-1]*i%p; inv[SIZE-1]=mypow(fac[SIZE-1],p-2); for(int i=SIZE-2;i>=0;i--) inv[i]=inv[i+1]*(i+1)%p; } void ADD(LL& x,LL v){ x=(x+v)%p; }