题目大意:
我们定义只含有4或者7的数为“幸运数”
现在给你L,R,问你L到R之间的幸运数的和
答案对10^9+7取模
(1<=l<r<=10^100000)
看到数字第一个想到的就是数位DP。
我们用sx[i][4]表示长度为i且开头为4的幸运数的和
用sx[i][7]表示长度为i且开头为7的幸运数的和
s[i][4]和s[i][7]分别表示长度为i的开头分别为4和7的幸运数个数
f[i][4]和f[i][7]分别表示长度为i的开头分别为4和7的ans
然后转移方程见程序,稍微手推一下应该就可以出来了
统计答案的时候从最高位开始减就可以了
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long f[100001][8];
long long s[100001][8];
long long sx[100001][8];
long long mod=1000000007;
inline long long power(long long x,int y)
{
long long t=1;
while(y!=0)
{
if(y%2==1)
t=t*x%mod;
y=y/2;
x=x*x%mod;
}
return t;
}
int main()
{
//freopen("288E.in","r",stdin);
//freopen("288E.out","w",stdout);
string l,r;
cin>>l>>r;
int len=l.size();
if(len==1)
{
if(l=="4"&&r=="7")
printf("28\n");
else
printf("0\n");
return 0;
}
f[2][4]=2068;
s[2][4]=1;
sx[2][4]=91;
f[2][7]=5698;
s[2][7]=1;
sx[2][7]=151;
sx[1][4]=4;
sx[1][7]=7;
long long x1=47,x2=74,xx=100;
long long xx1=44,xx2=77;
int i;
for(i=3;i<=len;i++)
{
long long x4=(long long)4*xx%mod,x7=(long long)7*xx%mod;
long long sxt=(long long)2*(sx[i-1][4]+sx[i-1][7])-xx1-xx2;
sxt%=mod;
while(sxt<0)
sxt+=mod;
f[i][4]=((f[i-1][4]+f[i-1][7]+x1*x2)%mod+(x4*x4%mod)*(s[i-1][4]+s[i-1][7]+(long long)1)%mod+x4*sxt%mod)%mod;
f[i][7]=((f[i-1][4]+f[i-1][7]+x1*x2)%mod+(x7*x7%mod)*(s[i-1][4]+s[i-1][7]+(long long)1)%mod+x7*sxt%mod)%mod;
s[i][4]=(s[i-1][4]+s[i-1][7]+(long long)1)%mod;
s[i][7]=(s[i-1][4]+s[i-1][7]+(long long)1)%mod;
sx[i][4]=(sx[i-1][4]+sx[i-1][7]+x4*(s[i][4]+(long long)1)%mod)%mod;
sx[i][7]=(sx[i-1][4]+sx[i-1][7]+x7*(s[i][7]+(long long)1)%mod)%mod;
x1=(x1*(long long)10+(long long)7)%mod;
x2=(x2*(long long)10+(long long)4)%mod;
xx=xx*(long long)10%mod;
xx1=(xx1*(long long)10+(long long)4)%mod;
xx2=(xx2*(long long)10+(long long)7)%mod;
}
long long px=power(10,mod-2);
long long ans=(f[len][4]+f[len][7]+x1*x2)%mod;
long long x4=0;
long long tx1=x1,tx2=x2,txx=xx;
for(i=len;i>=1;i--)
{
int dx=len-i;
if(l[dx]=='7')
{
long long xt=x4*xx%mod;
long long sxt=((long long)2*sx[i][4]-xx1-x1)%mod;
while(sxt<0)
sxt+=mod;
long long tt=(f[i][4]/*+x1*x2*/+(xt*xt%mod)*(s[i][4]/*+(long long)1*/)%mod+xt*sxt%mod)%mod;
tt=(tt+(xt+x1)*(xt+x2)%mod)%mod;
ans-=tt;
while(ans<0)
ans+=mod;
}
x4=(x4*(long long)10+(long long)(l[dx]-'0'))%mod;
x4%=mod;
xx=xx*px%mod;
x1=(x1-(long long)7)*px%mod;
while(x1<0)
x1+=mod;
x2=(x2-(long long)4)*px%mod;
while(x2<0)
x2+=mod;
xx1=(xx1-(long long)4)*px%mod;
while(xx1<0)
xx1+=mod;
}
long long x7=0;
x1=tx1;
x2=tx2;
xx=txx;
for(i=len;i>=1;i--)
{
int dx=len-i;
if(r[dx]=='4')
{
long long xt=x7*xx%mod;
long long sxt=((long long)2*sx[i][7]-xx2-x2)%mod;
while(sxt<0)
sxt+=mod;
long long tt=(f[i][7]/*+x1*x2*/+(xt*xt%mod)*(s[i][7]/*+(long long)1*/)%mod+xt*sxt%mod)%mod;
tt=(tt+(xt+x1)*(xt+x2)%mod)%mod;
ans-=tt;
while(ans<0)
ans+=mod;
}
x7=(x7*(long long)10+(long long)(r[dx]-'0'))%mod;
x7%=mod;
xx=xx*px%mod;
x1=(x1-(long long)7)*px%mod;
while(x1<0)
x1+=mod;
x2=(x2-(long long)4)*px%mod;
while(x2<0)
x2+=mod;
xx2=(xx2-(long long)7)*px%mod;
while(xx2<0)
xx2+=mod;
}
printf("%I64d\n",ans);
return 0;
}