Killer Names
HDU - 6143
取名字,名和字都有n个字母,并且由m个字母中取,要求名和字不能出现同一个字母。
ans=C1m∗1n∗(m−1)n+C2m∗(2n−C12∗1)∗(m−2)n+...
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9+7;
const int maxn = 2005;
LL f[maxn],c[maxn][maxn],n,m;
LL pow_mod(LL a,LL b) {
LL res = 1;
while(b) {
if(b&1) res = (res*a)%mod;
a = (a*a)%mod;
b>>=1;
}
return res;
}
void init() {
for(int i=0; i<maxn; i++) {
for(int j=0; j<=i; j++) {
if(!j||j==i) c[i][j] = 1;
else c[i][j] = (c[i-1][j] + c[i-1][j-1]) % mod;
}
}
}
int main() {
init();
int T;
scanf("%d",&T);
while(T--) {
scanf("%lld%lld",&n,&m);
LL ans = 0;
for(int i=1; i<=min(n,m); i++) {
LL res = (c[m][i] * pow_mod(m-i,n))%mod;
if(i==1) {
f[i]=1;
ans = (ans + res)%mod;
} else {
LL tmp = 0;
for(int j=1; j<i; j++) {
tmp = (tmp +f[j] * c[i][j])%mod;
}
f[i] = pow_mod(i,n) - tmp;
res = (res*f[i])%mod;
ans = (ans + res) % mod;
}
}
printf("%lld\n",ans);
}
return 0;
}