这道题我和队友磨了好久。。。写到后面其他题都没什么时间了,再加上一个队友没来,另一个队友1点半才来,我中途出去送一趟课堂考勤表。今天测试成绩很烂。。。
这题关键是恰好选出k种颜色,就是用k种颜色涂n个格子,每个颜色至少涂一个,彼此不相邻,的答案再乘c(m,k)。以前HNOI有道水题就是用k种颜色涂色,然后彼此不相邻,答案就是k*(k-1)^(n-1),这是有可能用,2,3,4,...k种不同的颜色涂满的情况之和,于是就要减去由(k-1)种颜色涂满这n个格子的和,C(k,k-1)*(k-1)*(k-2)^(n-1),然而由于从k种中选出k-1种,这个式子也是表示k-1,k-2,k-3...2种去涂的数量的总和,k-2又重复了,于是这就是一个容斥问题了。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<set>
using namespace std;
typedef long long LL;
const int maxl=1e6+50;
const LL mod=1e9+7;
LL C[maxl];
LL qp(LL a,LL b)
{
LL ans=1,cnt=a;
while(b)
{
if(b&1)
ans=(ans*cnt)%mod;
cnt=(cnt*cnt)%mod;
b>>=1;
}
return ans;
}
LL ck(LL k)
{
LL zi=1,mu=1;
for(LL i=1;i<=k;i++)
{
zi=(zi*(k-i+1))%mod;
mu=(mu*i)%mod;
C[i]=(zi*qp(mu,mod-2))%mod;
}
}
LL c(LL m,LL k)
{
LL zi=1,mu=1;
for(LL i=1;i<=k;i++)
{
zi=(zi*(m-i+1))%mod;
mu=(mu*i)%mod;
}
return (zi*qp(mu,mod-2))%mod;
}
LL n,m,k;
int main()
{
int T;cin>>T;
for(int kas=1;kas<=T;++kas){
scanf("%lld%lld%lld",&n,&m,&k);
ck(k);
LL ans=k*qp(k-1,n-1)%mod,tmp;
for(int i=1;k-i>=2;++i){
tmp = ((C[k-i]*(k-i))%mod)*qp(k-i-1,n-1)%mod;
if(i&1)ans=(mod+ans-tmp)%mod;
else ans=(ans+tmp)%mod;
}
ans=ans*c(m,k)%mod;
printf("Case #%d: %lld\n",kas,ans);
}
return 0;
}