分半搜索,枚举那几个数字分成两半的方案,然后暴力看它们组合Mod d 的余数,并记录,left[i]表示左边的有多少组合mod d = i ,right[i] 也相同,然后用简单数学方法合并
const int N = 15, M = 1010;
int Dat[N], TDat[N], Cnt[2][M], Ans;
int n, Mod;
char S[N];
inline void Solve() ;
inline void NextState(int x, int Pick) ;
inline void Input() {
int T;
for(scanf("%d", &T); T--; ) {
scanf("%s", S), n = strlen(S);
scanf("%d", &Mod);
clr(Dat, 0), clr(TDat, 0);
Rep(i, n) Dat[S[i] - '0']++;
Ans = 0, NextState(0, 0);
printf("%d\n", Ans);
}
}
inline void NextState(int x, int Pick) {
if(x >= n >> 1) Solve();
else {
For(i, Pick, 9)
if(TDat[i] < Dat[i]) {
TDat[i]++;
NextState(x + 1, i);
TDat[i]--;
}
}
}
inline void Dfs(int Last, int Now, int Type) {
if(!Last) Cnt[Type][Now % Mod]++;
else {
Rep(i, 10)
if(TDat[i]) {
TDat[i]--;
Dfs(Last - 1, Now * 10 + i, Type);
TDat[i]++;
}
}
}
inline void Solve() {
// Dfs
clr(Cnt, 0);
Dfs(n >> 1, 0, 0);
Rep(i, 10) TDat[i] = Dat[i] - TDat[i];
Dfs(n - (n >> 1), 0, 1);
Rep(i, 10) TDat[i] = Dat[i] - TDat[i];
// Count
int Size = 1;
Rep(i, n - (n >> 1)) Size *= 10;
Rep(i, Mod) Ans += Cnt[0][i] * Cnt[1][(Mod - (i * Size) % Mod) % Mod];
}
int main() {
#ifndef ONLINE_JUDGE
SETIO("1072");
#endif
Input();
Solve();
return 0;
}