Description
Input
Output
Sample Input
3 1 9 10 11 17 17
Sample Output
236 221 0
Source
思路:数位DP, 一个表示与7无关的个数,一个表示与7无关的数的和,7无关的数字的平方和。
难处理的是平方和,要从前两个推出来,就是将平方和拆出来就行了,还有乱mod不会过啊,
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef long long ll; const int maxn = 20; const ll mod = 1000000007ll; struct node { long long cnt; long long sum; long long sqsum; } dp[maxn][10][10]; ll p[maxn]; int num[maxn]; node dfs(int cur, int p1, int p2, int flag) { if (cur == -1) { node tmp; tmp.cnt = (p1 != 0 && p2 != 0); tmp.sum = tmp.sqsum = 0; return tmp; } if (!flag && dp[cur][p1][p2].cnt != -1) return dp[cur][p1][p2]; int end = flag?num[cur]:9; node ans; node tmp; ans.cnt = ans.sqsum = ans.sum = 0; for (int i = 0; i <= end; i++) { if (i == 7) continue; tmp = dfs(cur-1, (p1+i)%7, (p2*10+i)%7, flag&&i==end); ans.cnt += tmp.cnt; ans.cnt %= mod; ans.sum += (tmp.sum+ ((p[cur]*i)%mod)*tmp.cnt%mod)%mod; ans.sum %= mod; ans.sqsum += (tmp.sqsum + ((2*p[cur]*i)%mod)*tmp.sum)%mod; ans.sqsum %= mod; ans.sqsum += (tmp.cnt*p[cur])%mod*p[cur]%mod*i*i%mod; ans.sqsum %= mod; } if (!flag) dp[cur][p1][p2] = ans; return ans; } long long cal(long long m) { int cnt = 0; while (m) { num[cnt++] = m%10; m /= 10; } return dfs(cnt-1, 0, 0, 1).sqsum; } int main() { int t; p[0] = 1; for (int i = 1; i < maxn; i++) p[i] = (p[i-1]*10) % mod; for (int i = 0; i < maxn; i++) for (int j = 0; j < 10; j++) for (int k = 0; k < 10; k++) dp[i][j][k].cnt = -1; cin >> t; while (t--) { ll l, r; cin >> l >> r; long long ans = cal(r); ans -= cal(l-1); ans = (ans%mod+mod)%mod; cout << ans << endl; } return 0; }