题目

image-1678933624242

题解

递归

数据量较小时,可以使用数学公式:C[i][j]=C[i-1][j]+C[i-1][j-1];

#include<iostream>
using namespace std;
const int N=2010, mod=1e9+7;
int c[N][N];
void init(){
    for(int i=0;i<N;i++)
        for(int j=0;j<=i;j++)
            if(!j)c[i][j]=1;
            else c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
}

int main(){
    int n;
    cin>>n;
    init();
    while(n--){
        int a,b;
        cin>>a>>b;
        cout<<c[a][b]<<endl;
    }
    
    return 0;
}

快速幂求逆元

利用乘法逆元可以将除法变成乘法,如a/b->a*b-1
乘法逆元:b存在乘法逆元的充要条件是 b与模数 m互质。当模数 m为质数时,bm−2即为 b 的乘法逆元。
Cab=a! * b!-1 * (a-b)!-1

#include<iostream>
using namespace std;
typedef long long LL;
const int mod=1e9+7,N=100010;
int infact[N],fact[N];
LL qmi(int a,int b,int p){
    LL ans=1;
    while(b){
        if(b&1)ans=ans*a%p;
        a=(LL)a*a%p;
        b>>=1;
    }
    return ans;
}

int main(){
    infact[0]=fact[0]=1;
    for(int i=1;i<N;i++){
        fact[i]=(LL)fact[i-1]*i%mod;
        infact[i]=(LL)infact[i-1]*qmi(i,mod-2,mod)%mod;
    }
    int n;
    cin>>n;
    while(n--){
        int a,b;
        cin>>a>>b;
        cout<<(LL)fact[a]*infact[b]%mod*infact[a-b]%mod<<endl;
    }
    
    return 0;
}