版权声明:http://blog.csdn.net/Mitsuha_。 https://blog.csdn.net/Mitsuha_/article/details/82152976
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
给定一个数
,设它十进制展从高位到低位上的数位依次是
,定义交错和函数:
例如:
给定 ,求在 区间中,所有 的 的和,即:
输入
输入数据仅一行包含三个整数,
。
输出
输出一行一个整数表示结果,考虑到答案可能很大,输出结果模
。
提示
对于样例 ,满足条件的数有 110 和 121,所以结果是 231 = 110 + 121。
更多样例:
Input
4344 3214567 3
Output
611668829
Input
404491953 1587197241 1
Output
323937411
Input
60296763086567224 193422344885593844 10
Output
608746132
Input
100 121 -1
Output
120
样例输入
100 121 0
样例输出
231
思路:数位DP,用结构体 存储前 位的交错和为 , 表示在第 位是 的数的和以及这些数的个数。
交错和可能为负,所以假定 的时候和为0。
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+10;
const int MOD=1e9+7;
const double PI=acos(-1.0);
typedef long long ll;
struct lenka
{
ll sum,cnt;
}d[20][10][400][2];
int p[20];
ll f[20];
ll cal(ll x,ll num)
{
if(x<0)return 0;
int n=0;
while(x)p[n++]=x%10,x/=10;n--;
memset(d,0,sizeof d);
for(int i=0;i<=n;i++)
{
if(i==0)
{
for(int j=0;j<=9;j++)
{
d[i][j][200+j][0].sum=j;
d[i][j][200+j][0].cnt=1;
d[i][j][200-j][1].sum=j;
d[i][j][200-j][1].cnt=1;
}
continue;
}
for(int j=0;j<=9;j++)
{
for(int k=0;k<=9;k++)
for(int sum=200-9*i;sum<=200+9*i;sum++)
{
(d[i][j][sum-j][1].sum+=d[i-1][k][sum][0].sum+d[i-1][k][sum][0].cnt*j%MOD*f[i]%MOD)%=MOD;
(d[i][j][sum-j][1].cnt+=d[i-1][k][sum][0].cnt)%=MOD;
(d[i][j][sum+j][0].sum+=d[i-1][k][sum][1].sum+d[i-1][k][sum][1].cnt*j%MOD*f[i]%MOD)%=MOD;
(d[i][j][sum+j][0].cnt+=d[i-1][k][sum][1].cnt)%=MOD;
}
}
}
ll ans=0;
for(int i=0;i<n;i++)
{
for(int j=1;j<=9;j++)(ans+=d[i][j][num][0].sum)%=MOD;
}
ll dig=0,tot=0;
for(int i=n;i>=0;i--)
{
if(i==n)
{
for(int j=1;j<p[i];j++)(ans+=d[i][j][num][0].sum)%=MOD;
}
else
{
for(int j=0;j<p[i];j++)
{
(ans+=d[i][j][num-dig][(n-i)%2].sum)%=MOD;
(ans+=d[i][j][num-dig][(n-i)%2].cnt*tot%MOD)%=MOD;
}
}
if((n-i)%2==0)dig+=p[i];
else dig-=p[i];
(tot+=p[i]*f[i]%MOD)%=MOD;
}
return ans+(dig+200==num?tot:0);
}
int main()
{
f[0]=1;
for(int i=1;i<=19;i++)f[i]=f[i-1]*10%MOD;
ll L,R,k;
cin>>L>>R>>k;
printf("%lld\n",(cal(R,k+200)-cal(L-1,k+200)+MOD)%MOD);
return 0;
}