思路:

区间内找出不含7的个数以及区间这些数的和都是数位的板子题,求区间内不含7的数的平方和需要推导公式。
数位位数的结果时,是将位数的结果相加得到的。
这不像我们平时写的那些数位题只求满足条件的数的个数,所以我们可以考虑设成结构体数组,存符合条件的个数,存符合条件的数的和,存符合条件的数的平方和。

,表示满足条件的位数的结果。

最高位到第位的位数和的值为,最高位到第位的数值和的值为

,作用相当于:123,第3位是1,那么

那么

是存某个位数结果的结构体(第位是),是存ans后面某个位结果的结构体。

,于是可以求
位数符合条件的数的平方和已经存过了,即

需要注意的是,是包含多个数的,包含个符合条件的数。

表示当前位数 的结果是否有范围限制。

位数

MyCode:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7,mod=1e9+7;
inline ll read() {
    ll s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57) {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57)
        s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
ll inf[20];
inline void init() {
    inf[1]=1;
    for(int i=2; i<=19; ++i)
        inf[i]=inf[i-1]*10%mod;
}
struct node {
    ll cnt,sum,ssum;
    node() {
        cnt=-1;
        sum=ssum=0;
    }
} dp[23][10][10];
int digit[23];
node dfs(int len,int p1,int p2,int limit) {//1.当前是几位数 2.数位和%7的值 3.数值%7的值
    node ans,tmp;
    if(!len) {
        ans.cnt=(p1&&p2);
        return ans;
    }
    if(!limit&&dp[len][p1][p2].cnt!=-1) return dp[len][p1][p2];
    int endi=(limit?digit[len]:9);
    ans.cnt=0;
    for(ll i=0; i<=endi; ++i) {
        if(i==7) continue;
        tmp=dfs(len-1,(p1+i)%7,(p2*10+i)%7,limit&&i==endi);
        ll x=i*inf[len]%mod;//当前最高位的值
        ans.cnt=(ans.cnt+tmp.cnt)%mod;
        ans.sum=(ans.sum+x*tmp.cnt%mod+tmp.sum)%mod;
        ans.ssum=(ans.ssum+x*x%mod*tmp.cnt%mod+2*x*tmp.sum%mod+tmp.ssum)%mod;
    }
    if(!limit) dp[len][p1][p2]=ans;
    return ans;
}
ll solve(ll x) {
    int len=0;
    while(x) {
        digit[++len]=x%10;
        x/=10;
    }
    return dfs(len,0,0,1).ssum;
}
int main() {
    int t=read();
    init();
    while(t--) {
        ll l=read(),r=read();
        printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);
    }
    return 0;
}