描述
给定一个数 x,设它十进制展从高位到低位上的数位依次是
例如:
给定 l, r, k,求在 [l, r] 区间中,所有 f(x) = k 的 x 的和,即:
输入
输入数据仅一行包含三个整数,l, r, k
输出
输出一行一个整数表示结果,考虑到答案可能很大,输出结果模 109 + 7。
提示
对于样例 ,满足条件的数有 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的题,我们定义dp[i][j][k]表示第i位和为j状态为k时的x的和和数量,然后进行转移就行了。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL Mod = 1e9+7;
struct node {
LL num,sum;
}dp[65][410][2];
LL Cm[21];
int bite[70],Dnum,len;
void GetBite(LL n) {
Dnum = 0;
while(n) {
bite[++Dnum] = n%10;
n/=10;
}
}
node dfs(int pos,int aim,bool limits,bool Front) {
node rs;
rs.num= 0;
rs.sum = 0;
if(pos == 0) {
if(aim ==100){
rs.num = 1;
}
return rs;
}
if(!limits && !Front && dp[pos][aim][len%2].num !=-1){
return dp[pos][aim][len%2];
}
int end = limits?bite[pos]:9;
for(int i = Front;i<=end;i++) {
int add = (len-pos)%2 ?1:-1;
node Next = dfs(pos-1,aim+add*i,limits&&i==end,0);
rs.sum = (rs.sum+Next.sum+Next.num*Cm[pos]*i%Mod)%Mod;
rs.num = (rs.num+Next.num)%Mod;
}
if(!limits && !Front) {
dp[pos][aim][len%2] = rs;
}
return rs;
}
LL GetAns(LL n,int x) {
GetBite(n);
LL ans = 0;
for(len = 1;len<=Dnum;len++) {
ans = (ans+dfs(len,x+100,len == Dnum,1).sum)%Mod;
}
return ans;
}
void Init() {
Cm[1] = 1;
for(int i = 2;i<=20;i++) {
Cm[i] = (Cm[i-1]*10)%Mod;
}
}
LL L,R;
int aim;
int main() {
Init();
memset(dp,-1,sizeof(dp));
while(cin>>L>>R>>aim) {
cout<<((GetAns(R,aim)-GetAns(L-1,aim))%Mod+Mod)%Mod<<endl;
}
return 0;
}