/**
题意:从1 ~ N,选出若干个子集,满足子集里面任意两个数的任意两个数位没有相同的,一个数自身可以有相同的数位,求这样的子集的个数
思路:因为数字只有九个,考虑状压,先看状态为S的数(状态为0000000101代表只有2和0的数,比如200,20,220),设dp[S]:N以内子集状态为S
的数量,ans[S]:N以内的一个数的状态恰为S的数量,当选择状态为S的添加进集合时,那么有dp[T] += dp[K] * ans[S] (其中K交S为空集,
K|S为T),剩下就是计算ans[S],预处理出0~9,00~99,000~999...包含前导0的状态为S的数量res[S][1],res[S][2],res[S][3]....
剩下的是搜索,高位往低位搜索,当选择的位小于当前位的时候后面不用再去搜索了,因为怎么选择都可以,用res数组统计一下即可,当等于
的时候
**/
#include<bits/stdc++.h>
typedef long long ll;
const ll mod = 1e9 + 7;
const int maxn = 1200;
using namespace std;
struct P {
int S, num;
P() {}
P(int s, int n) : S(s), num(n) {}
bool operator < (P p) const {
if(num != p.num) return num < p.num;
return S < p.S;
}
void init() {
int s = S; num = 0;
while(s) {
if(s & 1) num++;
s >>= 1;
}
}
} p[maxn];
ll res[maxn][11], bit[11];
ll dp[maxn], ans[maxn];
int n, T, kase = 1;
void init() {
memset(res, 0, sizeof res);
for(int i = 0; i < 10; i++) res[1 << i][1] = 1;
for(int i = 2; i < 11; i++) {
for(int x = 0; x < 10; x++) {
int S = 1 << x;
for(int s = 0; s < 1024; s++) {
int T = s | S;
res[T][i] += res[s][i - 1];
res[T][i] %= mod;
}
}
}
for(int i = 0; i < 1024; i++) {
p[i] = P(i, 0);
p[i].init();
}
sort(p, p + 1024);
}
int solve(int n) {
int len = 0;
while(n) {
bit[++len] = n % 10;
n /= 10;
}
return len;
}
void dfs(int l, int S, int limit) {
if(!l) { ans[S]++; return ; }
if(!limit && S > 1) {
for(int x = 1; x < 1024; x++) {
int T = x | S;
ans[T] = (ans[T] + res[x][l]) % mod;
}
return ;
}
int up = limit ? bit[l] : 9;
for(int i = 0; i < up; i++) {
int newS = (S <= 1 && !i) ? 0 : S | (1 << i);
dfs(l - 1, newS, 0);
}
int newS = (S <= 1 && !up) ? 0 : S | (1 << up);
dfs(l - 1, newS, limit ? 1 : 0);
}
int main() {
init();
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
int len = solve(n);
memset(ans, 0, sizeof ans);
memset(dp, 0, sizeof dp);
dfs(len, 0, 1);
dp[0] = 1;
for(int i = 2; i < 1024; i++) {
int S = p[i].S;
for(int j = 1023; j >= 0; j--) {
int T = p[j].S;
if((S | T) != T) continue;
int K = T & (~S);
dp[T] = (dp[T] + dp[K] * ans[S] % mod) % mod;
}
}
ll t = 0;
for(int i = 2; i < 1024; i++) t += dp[i];
printf("Case %d: %lld\n", kase++, t % mod);
}
return 0;
}