交错和(数位dp)
交错和
数位DP
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 const int mod = 1e9 + 7; 5 6 struct Node{ 7 LL sum, cnt; 8 }dp[21][10][2][410]; 9 int bit[21]; 10 LL base[21]; 11 Node dfs(int pos, int cur, int lead, int lim, int sum){ 12 Node temp; 13 temp.sum = 0; temp.cnt = 0; 14 if(pos < 0) return temp; 15 if(!lim && dp[pos][cur][lead][sum + 200].cnt != -1) return dp[pos][cur][lead][sum + 200]; 16 if(pos == 0){ 17 if(sum == cur) { 18 temp.sum = sum; 19 temp.cnt = 1; 20 } 21 return temp; 22 } 23 int up = lim ? bit[pos - 1] : 9; 24 Node t; 25 for(int i = 0; i <= up; i++){ 26 if(lead) t = dfs(pos - 1, i, i == 0, lim && (i == up), sum); 27 else t = dfs(pos - 1, i, 0, lim && (i == up), cur - sum); 28 temp.cnt += t.cnt; 29 temp.sum = (temp.sum + t.sum + (t.cnt * cur % mod * base[pos]) % mod) % mod; 30 } 31 if(!lim) dp[pos][cur][lead][sum + 200] = temp; 32 return temp; 33 34 } 35 int k; 36 LL solve(LL x){ 37 int pos = 0; 38 while(x){ 39 bit[pos++] = x % 10; 40 x /= 10; 41 } 42 Node temp = dfs(pos, 0, 1, 1, k); 43 return temp.sum; 44 } 45 46 int main(){ 47 LL a, b; 48 base[0] = 1; 49 for(int i = 0; i < 21; i++){ 50 for(int j = 0; j < 10; j++){ 51 for(int k = 0; k < 2; k++){ 52 for(int p = 0; p < 410; p++) { 53 dp[i][j][k][p].sum = 0; 54 dp[i][j][k][p].cnt = -1; 55 } 56 } 57 } 58 } 59 for(int i = 1; i < 21; i++) base[i] = base[i - 1] * 10 % mod; 60 while(scanf("%lld %lld %d", &a, &b, &k) != EOF){ 61 printf("%lld\n", (solve(b) - solve(a - 1) + mod) % mod); 62 } 63 }