题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4507
需要维护三个数 个数count,满足条件数的和sum,数的平方和square;
一个数 = (a*10的pre次方+b);b<0的pre次方
一个数的平方 = (a*10的pre次方*a*10的pre次方 + 2*a*10的pre次方*b + b*b);
len时(len-1的数在nxt中)
count : 直接加nxt.cnt;
sum :加nxt.sum(对应b)加power10*nxt.cnt(对应b)
square :加 nxt.square 加 power10*power10%mod*nxt.cnt 加 2*power10*nxt.sum
注意经常%=1e+7;
#include <cstdio>
#include <cstring>
using namespace std;
typedef __int64 ll;
const ll mod = 1e9+7;
ll num[20];
Node dp[20][2][7][7];//dp[len][是否含7][数取模7][数位和去摸7];
bool vis[20][2][7][7];
Node dfs(int len, bool state, int yushu,int weihe,bool fp)
{
Node tmp;
tmp.cnt = 0;
tmp.sum = 0;
tmp.square = 0;
if(len == 0)
{
if(!state && yushu && weihe)
tmp.cnt = 1;
return tmp;
}
if(vis[len][state][yushu][weihe] && !fp)
return dp[len][state][yushu][weihe];
int fpmax = fp?num[len]:9;
for(int i = 0; i <= fpmax; i++)
{
ll power10 = i*pre[len-1]%mod;
Node nxt = dfs(len-1,state||(i==7),(yushu*10+i)%7,(weihe+i)%7,fp&&i==fpmax);
(tmp.cnt += nxt.cnt)%=mod;
(tmp.sum += nxt.sum+power10*nxt.cnt)%=mod;
(tmp.square += nxt.square + power10*power10%mod*nxt.cnt + 2*power10*nxt.sum)%=mod;
}
if(!fp)
{
vis[len][state][yushu][weihe] = true;
dp[len][state][yushu][weihe] = tmp;
}
return tmp;
}
ll cal(ll x)
{
int len = 0;
while(x)
{
num[++len] = x%10;
x/=10;
}
return dfs(len,false,0,0,true).square;
}
int main()
{
int t;
ll l,r;
scanf("%d",&t);
while(t--)
{
scanf("%I64d %I64d",&l,&r);
printf("%I64d\n", (cal(r)-cal(l-1)+mod)%mod);
}
return 0;
}