思路:先考虑满足不相邻的条件,很容易写出,C(k,m)*k*k^(n-1)。但是这样并不是严格使用了k种颜色的,还包括了使用了1,2,3,....k-1种颜色的,所以,我们需要将其去重。
去重当然是考虑容斥:设使用了前k种颜色为f[k],那么前k-1则为f[k-1],需要注意的是f[k-1]中包含k-2,k-3.....1,同理f[k-2]包括了k-3,k-4....1。
看下表:
f[i-1] | f[i-2] | f[i-3] | f[i-4] | |
i-1 | 没有 | 没有 | 没有 | |
i-2 | i-2 | 没有 | 没有 | |
i-3 | i-3 | i-3 | 没有 | |
i-4 | i-4 | i-4 | i-4 |
观看上面的表格,如果减去f[i-1]的话,相当于减去整个表格里的内容,一个 i-1, 两个 i-2, 三个 i-3 .....
因为减去了两个i-2,所以需要把i-2加回来一个,所以 + f[i-2] 就行,同样的分析 ,即可解释容斥原理。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1e6+7;
const int mod=1e9+7;
ll n,m;
int k;
ll inv[maxn];
ll c[maxn];
ll qpow(int a,int b)
{
ll ans=1;
ll aa=a;
while(b)
{
if(b&1)
{
ans=ans*aa%mod;
}
aa=aa*aa%mod;
b>>=1;
}
return ans;
}
void init_inv()
{
for(int i=1;i<maxn;i++)
{
inv[i]=qpow(i,mod-2);
}
}
void cal(ll n)
{
c[0]=1;
for(int i=1;i<=k;i++)
{
c[i]=(c[i-1]*(n-i+1))%mod*inv[i]%mod;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T;
cin>>T;
int Case=0;
init_inv();
while(T--)
{
scanf("%lld%lld%d",&n,&m,&k);
ll ans=0;
cal(k);
int sign=1;
for(int i=k;i>=1;i--,sign=-sign)
{
ans=(ans+sign*c[i]*i%mod*qpow(i-1,n-1)%mod+mod)%mod;
}
cal(m);
ans=ans*c[k]%mod;
printf("Case #%d: ",++Case);
printf("%lld\n",ans);
}
return 0;
}