对于一个串来说我们粗略的看,它有多少个子串只和它各个位置的相等关系有关,所以我们没必要在乎字符集有多大,只需要枚举n的所有划分,处理出cnt[i][j][k]cnt[i][j][k]cnt[i][j][k]表示长度为iii的串有jjj个不同的字符且有kkk个子串的方案,每一次枚举的时候要么后面加一个已经出现过的字符,要么加一个新的字符。这样搜索状态总数只有BellnBell_nBelln个,对于n=10n=10n=10绰绰有余。
对于每次询问,只需要枚举一下这个串有多少个不同的字符,然后组合数统计即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define rep1(i,x,y) for(int i=x;i<=y;i++)
typedef long long ll;
typedef unsigned long long llu;
const int base = 123;
const int N = 110;
const int mod = 1e9 + 7;
int ans[N] ;
llu tem[N];
ll a[11][11][N]={0};
void cal(int n,int co){
int cnt = 0;
rep1(i,1,n) {
llu ha = 0;
rep1(j,i,n) ha = ha*base+ans[j]+'a',tem[cnt++]=ha;
}
sort(tem,tem+cnt);
cnt = unique(tem,tem+cnt)-tem;
a[n][co][cnt]++;
}
void dfs(int p,int c){
rep1(i, 1 , c){
ans[p] = i;
cal(p,max(i,c-1));
if(p < 10) dfs(p+1,max(i+1,c));
}
}
int n,m,k;
ll c[N];
void init(){
c[0]=1;
rep1(i,1,min(n,k)) c[i] = c[i-1]*(k-i+1)%mod;
}
int main()
{
dfs(1 , 1);
int T;
scanf("%d",&T);
while(T--){
scanf("%d %d %d",&n,&m,&k);
init();
ll an = 0;
rep1(i,1,n){
an = (an + (ll)a[n][i][m]*c[i]%mod)%mod;
}
printf("%d\n",(int)an);
}
return 0;
}