题意:
统计[a, b]中有多少个数字满足:自身是k的倍数,而且各个数字之和也是k的倍数。
分析:
详细分析见《训练之南》吧,=_=||
书上提出了一个模板的概念,有了模板我们就可以分块计算。
虽然书上定义f(x)表示不超过x的非负整数且满足条件的个数,但为了编码方便,代码中f(x)的含义为0~x-1中满足条件的个数。
这样最终所求为f(b+1) - f(a)
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int MOD; 5 int pow_ten[10]; 6 int f[11][90][90]; 7 8 inline int mod(int n) 9 { return ((n % MOD) + MOD) % MOD; } 10 11 int F(int d, int m1, int m2) 12 { 13 if(d == 0) return m1 == 0 && m2 == 0 ? 1 : 0; 14 int& ans = f[d][m1][m2]; 15 if(ans >= 0) return ans; 16 17 ans = 0; 18 for(int x = 0; x <= 9; x++) 19 ans += F(d-1, mod(m1-x), mod(m2-x*pow_ten[d-1])); 20 return ans; 21 } 22 23 int sum(int n) 24 { 25 char digits[11]; 26 sprintf(digits, "%d", n); 27 int nd = strlen(digits); 28 29 int base = 0; 30 int sumd = 0; 31 int ans = 0; 32 for(int i = 0; i < nd; i++) 33 { 34 int na = nd - i - 1; 35 for(int d = 0; d < digits[i] - '0'; d++) 36 ans += F(na, mod(-sumd-d), mod(-base-d*pow_ten[na])); 37 sumd += digits[i] - '0'; 38 base += (digits[i] - '0') * pow_ten[na]; 39 } 40 return ans; 41 } 42 43 int main() 44 { 45 //freopen("in.txt", "r", stdin); 46 47 pow_ten[0] = 1; 48 for(int i = 1; i <= 9; i++) pow_ten[i] = pow_ten[i - 1] * 10; 49 50 int T, a, b; 51 scanf("%d", &T); 52 while(T--) 53 { 54 scanf("%d%d%d", &a, &b, &MOD); 55 if(MOD > 82) { puts("0"); continue; } 56 memset(f, -1, sizeof(f)); 57 printf("%d ", sum(b+1) - sum(a)); 58 } 59 60 return 0; 61 }