题意:n朵花,用m种颜色去染,恰好用k种颜色。相邻的不能用同一种颜色,问有多少种方案。
思路:首先m种颜色中取k种,n朵花中,第一朵k种颜色,之后每一朵都是k-1种颜色。但是这样并不是恰好k种颜色。需要容斥一下。
所以最后的公式是:
Ckm∗∑i=1kCik∗i∗(i−1)n−1∗(−1)k−i
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#define maxn 1000010
const long long mod =1000000007;
using namespace std;
long long inv[maxn];
long long c[maxn];
long long qpow(long long a,long long b){
long long ans=1;
a%=mod;
for(;b;b>>=1LL,a=a*a%mod)if(b&1LL)
ans=ans*a%mod;
return ans;
}
void init_yuan() {
inv[1]=1;
for(int i=2;i<maxn;i++){
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
}
}
int n,m,k;
void init_cki() {
c[0]=1;
for(int i=1;i<=k;i++) {
c[i]=c[i-1]*(k-i+1)%mod*inv[i]%mod;
}
}
long long C(int n,int m) {
long long ans=1;
m=min(m,n-m);
for(int i=n;i>=n-m+1;i--) {
ans=ans*i%mod;
}
for(int i=m;i>=1;i--) {
ans=ans*inv[i]%mod;
}
return ans;
}
int main()
{
init_yuan();
int t;
int kase=0;
scanf("%d",&t);
while(t--) {
scanf("%d%d%d",&n,&m,&k);
long long tot=0;
init_cki();
int fa=1;
for(int i=k;i>=1;i--) {
tot=(tot+fa*c[i]*i%mod*qpow(i-1,n-1)%mod+mod)%mod;
fa=-fa;
}
tot=(tot*C(m,k))%mod;
printf("Case #%d: %lld\n",++kase,tot);
}
return 0;
}