HDU 4507 数位dp
先保存一下代码,回头写题解。
View Code
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n) for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h) for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l) for((i) = (h); (i) >= (l); --(i)) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define Read() freopen("data.in", "r", stdin) #define Write() freopen("data.out", "w", stdout); typedef long long LL; const double eps = 1e-6; const double PI = acos(-1.0); const int inf = ~0u>>2; using namespace std; const int MOD = 1e9+7; struct node { LL num, sum, ssum; node() {} node(LL a, LL b, LL c) : num(a), sum(b), ssum(c) {} }dp[21][2][7][7]; int digit[21]; int len; int getlen(LL x) { int ret = 0; while(x) { digit[++ret] = x%10; x /= 10; } return ret; } void init() { for(int i = 0; i < 21; ++i) { for(int j = 0; j < 2; ++j) { for(int k = 0; k < 7; ++k) { for(int l = 0; l < 7; ++l) { dp[i][j][k][l] = node(0, 0, 0); } } } } } void solve() { int p, d, i, j, ii, jj; for(p = len; p > 0; --p) { for(d = 0; d < 10; ++d) { if(d == 7) continue; for(i = 0; i < 7; ++i) { for(j = 0; j < 7; ++j) { ii = (i + d)%7; jj = (j*10 + d)%7; // dp[p][1][ii][jj].sum += dp[p+1][1][i][j].sum*10 + dp[p+1][1][i][j].num*d; if(d < digit[p]) dp[p][1][ii][jj].sum += (dp[p+1][0][i][j].sum*10 + dp[p+1][0][i][j].num*d); dp[p][1][ii][jj].sum %= MOD; // dp[p][1][ii][jj].num += dp[p+1][1][i][j].num; if(d < digit[p]) dp[p][1][ii][jj].num += dp[p+1][0][i][j].num; dp[p][1][ii][jj].num %= MOD; // dp[p][1][ii][jj].ssum += dp[p+1][1][i][j].ssum*100LL + 20LL*dp[p+1][1][i][j].sum*d + dp[p+1][1][i][j].num*d*d; if(d < digit[p]) dp[p][1][ii][jj].ssum += dp[p+1][0][i][j].ssum*100LL + 20LL*dp[p+1][0][i][j].sum*d + dp[p+1][0][i][j].num*d*d; dp[p][1][ii][jj].ssum %= MOD; } } } d = digit[p]; if(d == 7) continue; for(i = 0; i < 7; ++i) { for(j = 0; j < 7; ++j) { if(!dp[p+1][0][i][j].num) continue; ii = (i + d)%7; jj = (j*10 + d)%7; // dp[p][0][ii][jj].sum += dp[p+1][0][i][j].sum*10 + dp[p+1][0][i][j].num*d; dp[p][0][ii][jj].sum %= MOD; // dp[p][0][ii][jj].num += dp[p+1][0][i][j].num; dp[p][0][ii][jj].num %= MOD; // dp[p][0][ii][jj].ssum += dp[p+1][0][i][j].ssum*100LL + 20LL*dp[p+1][0][i][j].sum*d + dp[p+1][0][i][j].num*d*d; dp[p][0][ii][jj].ssum %= MOD; } } } } LL cal(LL x) { init(); len = getlen(x); dp[len+1][0][0][0].num = 1; solve(); LL ans = 0; for(int i = 1; i < 7; ++i) { for(int j = 1; j < 7; ++j) { ans = (ans + dp[1][1][i][j].ssum)%MOD; ans = (ans + dp[1][0][i][j].ssum)%MOD; } } return ans%MOD; } int main() { //Read(); int T; LL a, b, ans; cin >> T; while(T--) { cin >> a >> b; ans = cal(b) - cal(a - 1); cout << (ans + MOD)%MOD << endl; } return 0; }