题目大意:求:
。500组数据。
题解:
直接暴做。
首先注意到
是一个关于
的
次多项式,设
,则:
其中:
可以在
时间内计算,其中
为第二类斯特林数。
综上,
均可在
时间内求出。
(实际上,关于
,可以使用一些关于生成函数的技巧得知其是一个
次多项式与
的乘积,可以使用拉格朗日插值在
时间内算出单项(所以说好像没啥用))
总之这样就做完了。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define mod 1000000007
#define lint long long
#define gc getchar()
#define N 310
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
int st[N][N],fac[N],facinv[N],inv[N],a[N],npm[N],pm2[N],f[N];
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
const int inv2=fast_pow(2,mod-2);
inline int prelude(int n)
{
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=(lint)fac[i-1]*i%mod;
facinv[n]=fast_pow(fac[n],mod-2);
for(int i=n-1;i>=0;i--) facinv[i]=(i+1ll)*facinv[i+1]%mod;
for(int i=1;i<=n;i++) inv[i]=(lint)fac[i-1]*facinv[i]%mod;
st[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
st[i][j]=(st[i-1][j-1]+(lint)j*st[i-1][j])%mod;
return 0;
}
inline int C(int n,int m)
{
if(n<0||m<0||n<m) return 0;
return (lint)fac[n]*facinv[m]%mod*facinv[n-m]%mod;
}
inline int get_ca(int k)
{
memset(a,0,sizeof(int)*(k+1)),a[0]=1;
for(int i=0;i<k;a[0]=0,i++) for(int j=i+1;j;j--)
a[j]=(a[j-1]-(lint)i*a[j]%mod+mod)%mod;
for(int i=0;i<=k;i++) a[i]=(lint)a[i]*facinv[k]%mod;
return 0;
}
int main()
{
prelude(N-1);
for(int T=inn();T;T--)
{
int n=inn(),m=inn(),k=inn();lint ans=0;get_ca(k);
// for(int i=0;i<=k;i++) debug(i)sp,debug(a[i])ln;
npm[0]=1;for(int i=1;i<=k;i++) npm[i]=(lint)npm[i-1]*(n+m)%mod;
pm2[0]=1;for(int i=1;i<=k;i++) pm2[i]=(lint)pm2[i-1]*(mod-2)%mod;
// for(int i=0;i<=k;i++) debug(i)sp,debug(npm[i])ln;
// for(int i=0;i<=k;i++) debug(i)sp,debug(pm2[i])ln;
for(int i=0,tm=fast_pow(2,m);i<=k;i++)
{
lint s=0;
for(int j=0,cmj=1,tmmj=tm;j<=i;j++)
s+=(lint)st[i][j]*fac[j]%mod*cmj%mod*tmmj%mod,
cmj=(lint)cmj*(m-j)%mod*inv[j+1]%mod,tmmj=(lint)tmmj*inv2%mod;
f[i]=(int)(s%mod);
}
for(int i=0;i<=k;i++)
{
lint s=0;
for(int t=0;t<=i;t++)
s+=(lint)C(i,t)*pm2[i-t]%mod*npm[t]%mod*f[i-t]%mod;
ans+=a[i]*(s%mod)%mod;
}
printf("%lld\n",ans%mod);
}
return 0;
}