P4609 [FJOI2016]建筑师

思路

裸的第一类斯特林数,思路和CF960G相同

预处理组合数和第一类斯特林数回答即可

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#define int long long
using namespace std;
const long long MOD= 1e9+7;
long long jc[300],inv[300],n,a,b,S_[50100][210];
long long pow(long long a,long long b){
    long long ans=1;
    while(b){
        if(b&1)
            ans=(ans*a)%MOD;
        a=(a*a)%MOD;
        b>>=1;
    }
    return ans%MOD;
}
long long S(long long n,long long k){
    if(k==0&&n==0)
        return 1;
    if(k==0||n==0)
        return 0;
    if(S_[n][k]!=-1)
        return S_[n][k];
    return S_[n][k]=(S(n-1,k-1)%MOD+(n-1)*S(n-1,k)%MOD)%MOD;
}
long long C(long long n,long long m){
    return jc[n]*inv[m]%MOD*inv[n-m]%MOD;
}
void init(void){
    jc[0]=inv[0]=1;
    for(int i=1;i<300;i++){
        jc[i]=jc[i-1]*i%MOD;
        inv[i]=pow(jc[i],MOD-2);
    }
} 
int T;
signed main(){
    memset(S_,-1,sizeof(S_));
    init();
    scanf("%lld",&T);
    while(T--){
        scanf("%lld %lld %lld",&n,&a,&b);
        if((!a)||(!b)||a+b-2>n-1){
            printf("0\n");
            continue;
        }
        if(n==1){
            printf("%lld\n",1);
            continue;
        }
        printf("%lld\n",S(n-1,a+b-2)*C(a+b-2,b-1)%MOD);
    }
    return 0;
}
posted @ 2019-02-25 19:59  dreagonm  阅读(114)  评论(0编辑  收藏  举报