SP28304 ADATEAMS - Ada and Teams 题解

发布时间 2023-11-19 00:35:06作者: HZOI-Isaac

题目传送门

前置知识

乘法逆元 | 排列组合

解法

简单的排列组合。从 \(n\) 个学校中选出 \(a\) 个学校,共有 \(\dbinom{n}{a}\) 种不同的方案数。选出的 \(a\) 个学校中每所学校再从 \(b\) 个人中选出 \(d\) 个人,共有 \(\dbinom{b}{d}^a\) 种不同的方案数。依据乘法原理,二者相乘即为所求。

另外,记得预处理阶乘和逆元。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define sort stable_sort 
#define endl '\n'
ll jc[1000001],inv[1000001],jc_inv[1000001];
ll C(ll n,ll m,ll p)
{
    if(n>=m&&n>=0&&m>=0)
    {
        return (jc[n]*jc_inv[m]%p)*jc_inv[n-m]%p;
    }
    else
    {
        return 0;
    }
}
ll qpow(ll a,ll b,ll p)
{
    ll ans=1;
    while(b>0)
    {
        if(b&1)
        {
            ans=ans*a%p;
        }
        b>>=1;
        a=a*a%p;
    }
    return ans;
}
int main()
{
    ll n,a,b,d,i,p=1000000007;
    inv[1]=1;
    jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1;
    for(i=2;i<=1000000;i++)
    {
        inv[i]=(p-p/i)*inv[p%i]%p;
        jc[i]=jc[i-1]*i%p;
        jc_inv[i]=jc_inv[i-1]*inv[i]%p;
    }
    while(cin>>n>>a>>b>>d)
    {
        cout<<C(n,a,p)*qpow(C(b,d,p),a,p)%p<<endl;
    }
    return 0;
}