题目:
给定一个数 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
解法:数位dp,dp[pos][aim][len%2],记录的是,长度为len,从pos以下位置,在没有任何约束的情况下,结果为aim的交错和。增加一维[len%2]是因为len的奇偶性会影响pos后每位的正负性。dp中,sum为所有结果为aim的数的交错和,n为所有结果为aim的数的个数。
代码:
/****************************************************** * @author:xiefubao *******************************************************/ #pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <vector> #include <algorithm> #include <cmath> #include <map> #include <set> #include <stack> #include <string.h> //freopen ("in.txt" , "r" , stdin); using namespace std; #define eps 1e-8 #define zero(_) (abs(_)<=eps) const double pi=acos(-1.0); typedef long long LL; const int Max=22; const LL INF=1e9+7; int bit[Max]; int len; int p=0; struct node { LL sum; LL n; }; node dp[22][400][2]; LL help[22]; node dfs(int pos,int aim,bool limit,bool stt) { node re; re.n=0; re.sum=0; if(pos==0) { if(aim==100) re.n=1; return re; } if(!limit&&!stt&&dp[pos][aim][len%2].n!=-1) { return dp[pos][aim][len%2]; } int end=limit?bit[pos]:9; int st= stt?1:0; for(int i=st; i<=end; i++) { int add=((len-pos)%2==0?-1:+1); node next=dfs(pos-1,aim+add*i,limit&&i==end,0); re.sum=(re.sum+next.sum+next.n*help[pos]*i%INF)%INF; re.n=(re.n+next.n)%INF; } if(!limit&&!stt) return dp[pos][aim][len%2]=re; return re; } LL getans(LL n,int aim) { if(n<=0) return 0; p=0; while(n) { bit[++p]=n%10; n/=10; } LL ans=0; for(len=1; len<=p; len++) { ans=(ans+dfs(len,aim+100,len==p,1).sum)%INF; } return ans; } int main() { LL l,r; int aim; memset(dp,-1,sizeof dp); help[1]=1; for(int i=2;i<22;i++) help[i]=(help[i-1]*10)%INF; while(cin>>l>>r>>aim) { cout<<(getans(r,aim)-getans(l-1,aim)+INF)%INF<<endl; } return 0; }
时间: 2024-10-08 20:49:47