标签:
给定一个数 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,求在 [l, r] 区间中,所有 f(x) = k 的 x 的和,即:
输入数据仅一行包含三个整数,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 <iostream> #include <cstdio> #include <cstring> using namespace std; typedef long long LL; const int MOD = (int) 1e9 + 7; int a[20]; LL base[20]; int k, len; struct P{ LL num, sum; P(LL a=-1, LL b=0):num(a),sum(b){ } } dp[20][320][3]; P dfs(int cur, int st, int pos, bool limit) { if(cur < 1) return P(st == 160 + k, 0); if(!limit && pos!=0 && dp[cur][st][pos].num != -1) return dp[cur][st][pos]; int end = limit ? a[cur] : 9; P ret(0,0); int new_st, new_pos; for(int i=0; i<=end; i++) { if(pos==0 && i==0) { new_pos = pos; new_st = st; } else { if(pos<2) new_pos = pos + 1; else new_pos = pos - 1; if(new_pos & 1) new_st = st + i; else new_st = st - i; } P p = dfs(cur-1, new_st, new_pos, limit&&i==end); ret.num = (ret.num + p.num) % MOD; ret.sum = (ret.sum + (p.num * i) % MOD * base[cur] % MOD + p.sum) % MOD; } if(!limit && pos!=0) dp[cur][st][pos] = ret; return ret; } int f(LL x) { len = 0; while(x) { a[++len] = x%10; x/=10; } return dfs(len, 160, 0, 1).sum; } void Init() { base[1] = 1; for(int i=2; i<=19; i++) { base[i] = base[i-1] * 10 % MOD; } } int main () { Init(); LL l, r; scanf("%lld%lld%d", &l, &r, &k); printf("%lld\n", (f(r) - f(l-1) + MOD) % MOD); return 0; }
标签:
原文地址:http://www.cnblogs.com/AcIsFun/p/5432881.html