hiho 1033 —— 交错和 【数位DP】

时间限制:10000ms 单点时限:1000ms 内存限制:256MB

描述

给定一个数 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,求在 [lr] 区间中,所有 f(x) = k 的 x 的和,即:

1405402477702.png

输入

输入数据仅一行包含三个整数,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;    
} 

 

posted on 2016-04-25 21:47  SuperChan  阅读(321)  评论(0编辑  收藏  举报

导航