二项式反演裸题+组合数递推
思路待补充
#include "bits/stdc++.h"
#define int long long
const int maxn = 1e5 + 10;
const int MAXN = 1e6 + 10;
const int mod = 1e9 + 7;
using namespace std;
void Exgcd(int a, int b, int &x, int &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
int x1, y1;
Exgcd(b, a%b, x1, y1);
x = y1;
y = x1 - (a/b)*y1;
}
int Inv[MAXN];///放逆元的数组
///得到逆元
void Get_Inv()
{
Inv[1] = 1;
for(int i=2; i<MAXN; i++)
{
int y;
Exgcd(i, mod, Inv[i], y);
Inv[i] = (Inv[i]%mod+mod)%mod;
}
}
int quick_pow(int x, int b) {
int base = 1;
while (b) {
if (b & 1) {
base = (base * x) % mod;
}
x = (x * x) % mod;
b >>= 1;
}
return base;
}
int n, m, k;
int cm[MAXN];
int ck[MAXN];
void Get_Fac()
{
cm[0] = ck[0] = 1;
for(int i=1; i<=k; i++)
{
cm[i] = (cm[i-1]%mod * (m-i+1)%mod * Inv[i]%mod) % mod;
ck[i] = (ck[i-1]%mod * (k-i+1)%mod * Inv[i]%mod) % mod;
}
}
signed main() {
// freopen("in.txt","r",stdin);
int T;
cin >> T;
Get_Inv();
int id = 0;
while (T--) {
cin >> n >> m >> k;
int t = 0;
Get_Fac();
for (int i = 1; i <= k; ++i) {
t = ( t + quick_pow(-1, k - i) * ck[i] * i % mod * quick_pow(i - 1, n - 1) + mod) % mod;
}
printf("Case #%lld: %lld\n",++id,t * cm[k] % mod);
}
}