描述
给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数:
f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1
例如:
f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4
给定
输入
输入数据仅一行包含三个整数,l, r, k(0 ≤ l ≤ r ≤ 1018, |k| ≤ 100)。
输出
输出一行一个整数表示结果,考虑到答案可能很大,输出结果模 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
#include #include #include #include #define M 1000000007 int k, nod, digit[20]; long long b[20]; struct node { long long n, s;//n是具有相同位数的数的个数,s是n个数的和 }a[20][201];//第一维表示不同的位数,第二维:|k|<=100,所以0= <=200 node dfs(int d, int e, int flag) { node tmp, t; tmp.n = tmp.s = t.n = t.s = 0; if(!d) { if(e == 100)//处理到最后一位,因为最高位符号是从-1开始,且最初位和是从k+100开始,当e=100时,满足 tmp.n = 1; return tmp; } if(!flag && a[d][e].n != -1)//当位数不是最长位数且处理到该位数时的n不是-1 return a[d][e]; int sgn = ((nod - d) % 2 ? 1 : -1);//确定正负号 int start = (d == nod ? 1 : 0);//当处理位数d为nod时,nod位只能从1开始 int end = (flag ? digit[d] : 9);//flag为1表示处理到最长位数的数,此时最长位数的最高位只能小于等于该位的值 for(int i = start; i <= end; i++) { tmp = dfs(d - 1, e + sgn * i, flag && i == digit[d]); if(tmp.n) { t.n += tmp.n; int q = tmp.n % M * i % M * b[d] % M; t.s += tmp.s % M; t.s %= M; t.s += q; t.s %= M; } } if(!flag) a[d][e] = t; return t; } int calc(long long num)//计算[1,num]区间所有满足数之和 { int cnt = 1, sum = 0; while(num) { digit[cnt++] = num % 10; num /= 10; } for(nod = 1; nod < cnt; nod++) { memset(a, -1, sizeof(a)); sum += dfs(nod, k + 100, nod == cnt - 1).s % M; sum %= M; } return sum; } int main(void) { long long l, r; scanf("%lld%lld%d", &l, &r, &k); for(int i = 1; i < 20; i++) { b[i] = pow(10.0, i - 1); b[i] %= M; } printf("%d\n", (calc(r) - calc(l - 1) + M) % M); //system("pause"); }