吉哥系列故事——恨7不成妻
∑
i
=
1
n
(
p
r
e
+
s
u
c
)
2
∑
i
=
1
n
p
r
e
2
+
s
u
c
2
+
2
×
p
r
e
×
s
u
c
n
×
p
r
e
2
+
∑
s
u
c
2
+
2
×
p
r
e
∑
s
u
c
\sum_{i = 1} ^{n}(pre + suc) ^ 2\\ \sum_{i = 1} ^{n} pre ^ 2 + suc ^ 2 + 2 \times pre \times suc\\ n \times pre ^ 2 + \sum suc ^ 2 + 2 \times pre \sum suc\\
i=1∑n(pre+suc)2i=1∑npre2+suc2+2×pre×sucn×pre2+∑suc2+2×pre∑suc
所以考虑维护
c
n
t
,
s
u
m
,
s
u
m
2
cnt, sum, sum ^ 2
cnt,sum,sum2即可。
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
inline int add(int x, int y) {
return x + y < mod ? x + y : x + y - mod;
}
inline int sub(int x, int y) {
return x >= y ? x - y : x - y + mod;
}
struct Res {
int cnt, sum1, sum2;
}f[20][10][10];
int num[20], p[20], cnt;
Res dfs(int pos, int sum, int remain, int flag) {
if (!pos) {
if (sum != 0 && remain != 0) {
return {1, 0, 0};
}
else {
return {0, 0, 0};
}
}
if (!flag && f[pos][sum][remain].cnt != -1) {
return f[pos][sum][remain];
}
Res ans = {0, 0, 0};
int nex = flag ? num[pos] : 9;
for (int i = 0; i <= nex; i++) {
if (i == 7) {
continue;
}
Res cur = dfs(pos - 1, (sum + i) % 7, (remain * 10 + i) % 7, i == nex && flag);
ans.cnt = add(ans.cnt, cur.cnt);
int s = 1ll * i * p[pos] % mod;
ans.sum1 = add(ans.sum1, add(1ll * s * cur.cnt % mod, cur.sum1));
ans.sum2 = add(add(ans.sum2, 1ll * cur.cnt * s % mod * s % mod), add(cur.sum2, 2ll * s % mod * cur.sum1 % mod));
}
if (!flag) {
f[pos][sum][remain] = ans;
}
return ans;
}
int calc(long long x) {
cnt = 0;
while (x) {
num[++cnt] = x % 10;
x /= 10;
}
return dfs(cnt, 0, 0, 1).sum2;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 10; j++) {
for (int k = 0; k < 10; k++) {
f[i][j][k].cnt = -1;
}
}
}
p[1] = 1;
for (int i = 2; i < 20; i++) {
p[i] = 1ll * p[i - 1] * 10 % mod;
}
int T;
scanf("%d", &T);
while (T--) {
long long l, r;
scanf("%lld %lld", &l, &r);
printf("%lld\n", sub(calc(r), calc(l - 1)));
}
return 0;
}