hiho#1033 : 交错和

描述

给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - 1,定义交错和函数:

f(x) = a0 - a1 + a2 - ... + ( - 1)n - 1an - 1

例如:

f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4

给定 

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

显然是很裸的数位DP,但写起来就有些MD了。
设f[len][x][k]表示长度为len,首位为x,交错和为k的数之和,g[len][x][k]表示长度为len,首位为x,交错和为k的数的个数。
然后转移比较简单自己歪歪或看我的code,询问时注意:rep(i,0,len-2) rep(j,1,9) (res+=f[i][j][k+200])%=MOD; MD调了2h。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
typedef long long ll;
ll f[20][10][410],g[20][10][410],xp[20];
const int MOD=1000000007;
void init() {
    rep(i,0,9) f[0][i][i+200]=i,g[0][i][i+200]=1;
    xp[0]=1;
    rep(len,1,19) {
        xp[len]=(xp[len-1]*10)%MOD;
        rep(k,-200,200) rep(x,0,9) rep(y,0,9) if(x-k>=-200&&x-k<=200) {
            f[len][x][x-k+200]+=f[len-1][y][k+200]+(g[len-1][y][k+200]*(xp[len]*x))%MOD;
            (g[len][x][x-k+200]+=g[len-1][y][k+200])%=MOD;
            f[len][x][x-k+200]%=MOD;
        }
    }
}
int bit[20],len,k;
ll cal(ll x) {
    if(x<=0) return 0;
    ll res=0,cur2=0;int cur=0,c=0;len=0;
    while(x) bit[len++]=x%10,x/=10;
    rep(i,0,len-2) rep(j,1,9) (res+=f[i][j][k+200])%=MOD;
    dwn(i,len-1,0) {
        c^=1;
        rep(j,0,bit[i]-1) {
            if(!j&&i==len-1) continue;
            if(c) (res+=f[i][j][k-cur+200]+g[i][j][k-cur+200]*cur2)%=MOD;
            else (res+=f[i][j][cur-k+200]+g[i][j][cur-k+200]*cur2)%=MOD;
        }
        if(c) cur+=bit[i];
        else cur-=bit[i];
        (cur2+=bit[i]*xp[i])%=MOD;
    }
    return res;
}
int main() {
    init();
    ll l,r;
    scanf("%lld%lld",&l,&r);k=read();
    printf("%lld\n",(cal(r+1)-cal(l)+MOD)%MOD);
    return 0;
}
View Code

 

posted @ 2015-09-06 16:20  wzj_is_a_juruo  阅读(407)  评论(0编辑  收藏  举报