若菜的回忆….
比赛的时候推出公式为,WA了后用JAVA对拍了大数据,发现没问题,后来才发现是这是不大于k种颜色的涂法数,那时不知道容斥原理 T_T,果然弱啊…
正确的做法应该是容斥掉下面的颜色数
组合数因为k不大可以直接逆元处理,注意逆元先预处理出来
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
using namespace std;
long long MOD=1000000007;
long long n,m,k;
long long fac[1000005],inv[1000005];
long long pow_mod(long long a,long long b,long long m)
{
long long ans=1LL;a%=m;
while(b)
{
if(b&1LL)ans=ans*a%m;
b>>=1LL;a=a*a%m;
}
return ans;
}
void init(long long k)
{
fac[0]=1LL;
for(long long i=1;i<=k;++i)
{
fac[i]=(fac[i-1]*inv[i])%MOD*(k-i+1);
fac[i]%=MOD;
}
}
long long c(long long m,long long k)
{
long long c=1LL;
for(long long i=1;i<=k;++i)
{
c=(c*(m-i+1)%MOD*inv[i])%MOD;
}
return c;
}
long long go()
{
long long f=1;
long long ans=0LL; init(k);
for(long long i=k;i>=1;--i)
{
ans+=(f*fac[i]*i)%MOD*pow_mod(i-1,n-1,MOD)%MOD;
if(ans<0)ans+=MOD;
f=-f;
}
return ans%MOD;
}
int main()
{
//freopen("in.txt","r",stdin);
for(int i=1;i<=1000003;++i)inv[i]=pow_mod(i,MOD-2,MOD);
int cas=1,T;scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d",&n,&m,&k);
long long ans=c(m,k)%MOD*go();
printf("Case #%d: %I64d\n",cas++,ans%MOD);
}
return 0;
}