分析:简单的数位统计
f[i][j]表示第i位为j的方案数,显然f数组是满足区间减法的,即[1,B]的f的值减去[1,A-1]的f的值便是[A,B]的f数组的值,我们的得到了f数组后就很好解决了:
只需枚举位数i和数对的第i位,j和k:ans+=abs(j-k)*f[i][j]*f[i][k]
下面便是代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#define maxlen 50010
#define Mod 1000000007
#define LL long long
using namespace std;
char A[maxlen],B[maxlen];
int lenr,lenl,len,L[maxlen],R[maxlen];
LL f[maxlen][10],g[maxlen],ten[maxlen],ans;
void Calc()
{
ten[0]=1;
for (int i=1;i<=maxlen;i++) ten[i]=(ten[i-1]*10)%Mod;
LL r=0;
lenr=strlen(B+1);
for (int i=1;i<=lenr;i++) R[i]=B[lenr-i+1]-'0';
g[lenr+1]=0;
for (int i=lenr;i;i--) g[i]=(g[i+1]*10+R[i])%Mod;
for (int i=1;i<=lenr;i++)
{
for (int j=0;j<=9;j++)
{
f[i][j]=(g[i+1]*ten[i-1])%Mod;
if (j<R[i]) f[i][j]=(f[i][j]+ten[i-1])%Mod;
else if (j==R[i]) f[i][j]=(f[i][j]+r+1)%Mod;
}
r=(r+R[i]*ten[i-1])%Mod;
}
lenl=strlen(A+1);
for (int i=1;i<=lenl;i++) L[i]=A[lenl-i+1]-'0';
L[1]--;
for (int i=1;i<=lenl;i++) if (L[i]<0){L[i]+=10;L[i+1]--;}
while (lenl>1 && !L[lenl]) lenl--;
lenl=lenr;
memset(g,0,sizeof g);
for (int i=lenl;i;i--) g[i]=(g[i+1]*10+L[i])%Mod;
r=0;
for (int i=1;i<=lenl;i++)
{
for (int j=0;j<=9;j++)
{
f[i][j]=(f[i][j]-g[i+1]*ten[i-1]+Mod)%Mod;
if (j<L[i]) f[i][j]=(f[i][j]-ten[i-1]+Mod)%Mod;
else if (j==L[i]) f[i][j]=(f[i][j]-r-1+Mod)%Mod;
}
r=(r+L[i]*ten[i-1])%Mod;
}
len=max(lenr,lenl);
ans=0;
for (int i=1;i<=len;i++)
for (int j=0;j<=9;j++)
for (int k=0;k<=9;k++) ans=(ans+f[i][j]*f[i][k]*abs(j-k))%Mod;
}
int main()
{
scanf("%s%s",A+1,B+1);
Calc();
cout<<ans<<endl;
return 0;
}