题目:求在一定区间内和7无关的数字的平方和。
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
基本思想是(x+y)^2=x^2+2*x*y+y^2 维护sum和sqrt_sum,以及数量cnt来确定用了几次x^2。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
struct node{
ll cnt;
ll sum;
ll sqsum;
};
int t,wei[20];
ll A,B,p[20];
node dp[20][10][10];
node dfs(int pos,int s1,int s2,int limit)
{
if(pos<1)
{
node fuck;
fuck.cnt=(s1!=0&&s2!=0);
fuck.sum=fuck.sqsum=0;
return fuck;
}
if(!limit&&dp[pos][s1][s2].cnt!=-1)
return dp[pos][s1][s2];
int up=limit?wei[pos]:9;
node ans,tmp;
ans.cnt=ans.sum=ans.sqsum=0;
for(int i=0;i<=up;i++)
{
if(i==7)continue;
tmp=dfs(pos-1,(s1+i)%7,(s2*10+i)%7,limit&&i==up);
(ans.cnt+=tmp.cnt)%=mod;
(ans.sum+=tmp.sum+tmp.cnt*i%mod*p[pos]%mod)%=mod;
(ans.sqsum+=2ll*i*p[pos]%mod*tmp.sum%mod)%=mod;//求2xy
(ans.sqsum+=1ll*i*i%mod*p[pos]%mod*p[pos]%mod*tmp.cnt%mod+tmp.sqsum)%mod;//x^2+y^2
}
if(!limit)dp[pos][s1][s2]=ans;
return ans;
}
ll solve(ll x)
{
int len=0;
while(x)
{
wei[++len]=x%10;
x/=10;
}
node ans=dfs(len,0,0,1);
return ans.sqsum;
}
void init()
{
for(int i=0;i<20;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
dp[i][j][k].cnt=-1;
p[1]=1ll;
for(int i=2;i<20;i++)
p[i]=p[i-1]*10ll%mod;
}
int main()
{
init();
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld",&A,&B);
ll ans=(solve(B)-solve(A-1)+mod)%mod;
printf("%lld\n",ans);
}
return 0;
}