杰西最近在研究卷积,例如一个数字1234,那么经过杰西的变换后,就会变成1*4+2*3+3*2+4*1,例如一个数字是234,那么就会变成2*4+3*3+4*2。
形象化的,我们可以设f(x)表示x经过杰西变换后的值。用公式表示 x=dn−1dn−2...d2d1d0 那么 f(x)=∑n−1i=0di∗dn−1−i
例如f(1234)=20,f(234)=25。
现在他想到了一个问题。
如果他想知道对于所有i=L~R时的f(i)的值的和,该怎么做呢。
现在这个问题交给了你。
但是这个答案可能会非常大,因此杰西只想知道最终答案对1000000007取模后的答案。
Input
单组测试数据 一行两个整数L,R(1<=L<=R<=10^18)。
Output
一个数表示答案。
Input示例
3 233
Output示例
8730
System Message
(题目提供者)
C++的运行时限为:1000 ms ,空间限制为:131072 KB
示例及语言说明请按这里
允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章
感觉是一道比较烦的数位DP,情况比较多,看了题解看了很久才看明白23333,然后自己对着码了一遍,算是理解透彻了。。。比较难写,代码中加了一些注释。。。
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<functional>
using namespace std;
typedef long long ll;
#define inf 1000000000
#define mod 1000000007
#define maxn 1000005
#define lowbit(x) (x&-x)
#define eps 1e-9
ll digit[25],q[25];
void init()
{
q[1]=1;
for(int i=2;i<=20;i++)
q[i]=q[i-1]*10%mod;
}
ll dp(ll x,int a,int b,int v)
{
ll res=0;
int i,j,len=a+b-1;
if(v==0)
{
if(a==1)
return q[a+b-2]*2025%mod;
else
return q[a+b-3]*9*2025%mod;
}
else//类似奇数位求贡献的方法,注意细节
{
for(i=len;i>b;i--)
res=(res+(digit[i]-(i==len))*2025*q[i-2]%mod)%mod;
for(i=1;i<digit[b];i++)
res=(res+q[b-1]*45*i%mod)%mod;
for(i=b-1;i>a;i--)
res=(res+digit[i]*q[i-1]*digit[b]*45%mod)%mod;
for(i=1;i<digit[a];i++)
res=(res+q[a]*digit[b]*i%mod)%mod;
res=(res+(x%q[a]+1)*digit[a]*digit[b]%mod)%mod;
}
return res;
}
ll solve(ll x)
{
if(x<1) return 0;
int i,j,len=0;
ll tmp=x,res=0;
while(tmp)
{
digit[++len]=tmp%10;
tmp/=10;
}
for(i=1;i<=len;i++)
{
if(2*i-1>len)
break;
if(2*i-1<len)//位数小于上限时中间位的总贡献
{
if(i==1)
res=(res+285)%mod;
else
res=(res+q[2*i-2]*9*285%mod)%mod;
}
if(2*i-1==len)
{
for(j=len;j>i;j--)//计算比中间位高的位数上的数发生变化时的贡献
res=(res+(digit[j]-(j==len))*285*q[j-1]%mod)%mod;
for(j=1;j<digit[i];j++)//高位不变,中间位变化时的贡献
res=(res+q[i]*j*j%mod)%mod;
res=(res+digit[i]*digit[i]*(x%q[i]+1)%mod)%mod;//仅低位变化时的贡献
}
}
for(i=1;i<=len;i++)//计算成对卷积和
for(j=i+1;j<=len;j++)
{
if(i+j-1>len)
break;
res=(res+2*dp(x,i,j,i+j-1==len)%mod)%mod;
}
return res;
}
int main(void)
{
init();
ll l,r;
while(scanf("%lld%lld",&l,&r)!=EOF)
{
printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);
}
return 0;
}