dp[i][mod1][mod2][0] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的累加值的和
dp[i][mod1][mod2][1] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的累加平方值的和
dp[i][mod1][mod2][2] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的数量和
然后累加值 和 数量都是最普通的数位dp基本模型可以求出
平方和 的状态转移可以由 (a+b) ^ 2这个式子转移 既(a * ten[i]) ^ 2 * sum2 + sum1 + 2 * a * ten[i] * sum0 * sum2
注意取模
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define mod 1000000007ll
#define LL long long
using namespace std;
LL dp[31][11][11][3]; // 0 累加和 1 平方和 2 数量和
int sym[31][7][7];
LL x[100], l, ten[111];
void dfs(LL i, LL pre1, LL pre2, bool e, LL &sum1, LL &sum2, LL &sum3)
{
if(i == -1)
{
if(pre1 % 7 != 0 && pre2 % 7 != 0) sum3 = 1;
return ;
}
if(e && sym[i][pre1 % 7][pre2 % 7])
{
sum1 += dp[i][pre1 % 7][pre2 % 7][0];
sum2 += dp[i][pre1 % 7][pre2 % 7][1];
sum3 += dp[i][pre1 % 7][pre2 % 7][2];
sum1 %= mod;
sum2 %= mod;
sum3 %= mod;
return ;
}
int Max = e ? 9 : x[i];
for(int j = 0; j <= Max; j++)
{
if(j != 7)
{
LL sum11 = 0;
LL sum22 = 0;
LL sum33 = 0;
dfs(i - 1, pre1 + j, pre2 + ten[i] * j, !(!e && j == x[i]), sum11, sum22, sum33);
sum3 += sum33;
sum1 += sum11 + (sum33 % mod)* (j % mod) * (ten[i] % mod);
sum2 += (j * (ten[i] % mod) * j % mod * (ten[i] % mod) % mod * (sum33 % mod) % mod + sum22 % mod + 2 * (ten[i] % mod) * j % mod * (sum11 % mod) % mod) % mod;
sum1 %= mod;
sum2 %= mod;
sum3 %= mod;
}
}
if(e)
{
sym[i][pre1 % 7][pre2 % 7] = 1;
dp[i][pre1 % 7][pre2 % 7][0] = sum1;
dp[i][pre1 % 7][pre2 % 7][1] = sum2;
dp[i][pre1 % 7][pre2 % 7][2] = sum3;
dp[i][pre1 % 7][pre2 % 7][0] %= mod;
dp[i][pre1 % 7][pre2 % 7][1] %= mod;
dp[i][pre1 % 7][pre2 % 7][2] %= mod;
}
}
LL cal(LL n)
{
l = 0;
while(n)
{
x[l++] = n % 10;
n /= 10;
}
LL ans1 = 0, ans2 = 0, ans3 = 0;
dfs(l - 1, 0, 0, 0, ans1, ans2, ans3);
return ans2;
}
int main()
{
ten[0] = 1;
for(int i = 1; i<= 20; i++) ten[i] = ten[i - 1] * 10;
int t;
scanf("%d", &t);
while(t--)
{
LL a, b;
scanf("%I64d %I64d", &a, &b);
printf("%I64d\n", (cal(b) - cal(a - 1) + mod) % mod);
}
return 0;
}