由二项式反演公式可知
题意:给n盆花涂色,从m种颜色中选取k种颜色涂,保证正好用上k种颜色,你必须用上这k种颜色去涂满n个相邻的花,并且要求相邻花的颜色不同,求方案数。
只用k种花染色,考虑不全用上的方案数;
第一盆为k种颜色,之后的所有盆都为k-1种;
则总方案数为k*(k-1)^(n-1);
设用i种颜色两两相邻不一样颜色的方案数为g(i)
则有k*(k-1)^(n-1)=
设f(x)=x*(x-1)^(k-1)
f根据反演公式
g(k)=
最后答案再乘个C(m,k);
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAXN 1000005
int f[MAXN],fav[MAXN];
int inv[MAXN];
const LL MOD =(LL)1e9+7;
void init()
{
f[0]=fav[0]=1;
inv[1]=1;
for(int i=2;i<MAXN;i++)
{
inv[i]=(MOD-MOD/i)*1ll*inv[MOD%i]%MOD;
}
for(int i=1;i<MAXN;i++)
{
f[i]=f[i-1]*1ll*i%MOD;
fav[i]=fav[i-1]*1ll*inv[i]%MOD;
}
}
int comb(int n,int m)
{
if(m<0||m>n)return 0;
return f[n]*1ll*fav[n-m]%MOD*fav[m]%MOD;
}
LL pow_mod(LL a,LL b)
{
LL ans=1;
while(b)
{
if(b&1)ans=(a*ans)%MOD;
a=(a*a)%MOD;
b>>=1;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
int cas=1;
init();
while(t--)
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
LL ans=0;
int flag=(k&1)?1:-1;
for(int i=1;i<=k;i++)
{
ans=(ans+(1ll*flag*comb(k,i)*i%MOD*pow_mod(i-1,n-1)%MOD)%MOD+MOD)%MOD;
flag=-flag;
}
LL tmp=fav[k];
for(int i=1;i<=k;i++)
{
tmp=1ll*tmp*(m-k+i)%MOD;
}
ans=((1ll*ans*tmp)%MOD+MOD)%MOD;
printf("Case #%d: %lld\n", cas++, ans);
}
}