时间限制:10000ms
单点时限:1000ms
内存限制:256MB
-
100 121 0
样例输出 -
231
简单的数位dp,状态要记录两个,分别为状态出现的次数,状态的和。
代码如下:
#include <iostream> #include <algorithm> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <functional> #include <sstream> #include <iomanip> #include <cmath> #include <cstdlib> #include <ctime> //#pragma comment(linker, "/STACK:102400000,102400000") typedef long long ll; #define INF 1e9 #define MAXN 21 #define maxn 360 #define mod 1000000007 #define eps 1e-7 #define pi 3.1415926535897932384626433 #define rep(i,n) for(int i=0;i<n;i++) #define rep1(i,n) for(int i=1;i<=n;i++) #define scan(n) scanf("%d",&n) #define scanll(n) scanf("%I64d",&n) #define scan2(n,m) scanf("%d%d",&n,&m) #define scans(s) scanf("%s",s); #define ini(a) memset(a,0,sizeof(a)) #define out(n) printf("%d\n",n) ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);} using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct node { ll cnt,sum; //分别表示该状态的出现的次数,以及数字和 node(ll _cnt,ll _sum):cnt(_cnt),sum(_sum){} node(){} }dp[20][20][300]; //dp[i][j][k],表示当前在的i位,第一位有效位为j,交错和为k-100的状态 ll num[20]; ll ten[20]; ll l,r; int k; node dfs(int cur,int first,int sum,bool limit) { if(cur <= 0) return node(sum==k,0); if(!limit && dp[cur][first][sum+100].cnt != -1) return dp[cur][first][sum+100]; int up = limit ? num[cur] : 9; node ret(0,0),tv; rep(i,up+1) { int g; if(!first){ g = (i == 0 ? 0 : cur); } else g = first; if(g) tv = dfs(cur-1,g,sum+((g-cur)%2==0?1:-1)*i,limit && i == up); else tv = dfs(cur-1,0,0,limit && i==up); ll t = i*ten[cur-1]%mod; ret.cnt = (ret.cnt + tv.cnt) % mod; //次数相加 ret.sum = (ret.sum + tv.sum + t*tv.cnt)%mod; //和相加 } if(!limit) dp[cur][first][sum+100] = ret; return ret; } ll solve(ll n) { if(n <= 0) return 0; int len = 0; while(n){ num[++len] = n % 10; n /= 10; } return dfs(len,0,0,1).sum; } void init() { memset(dp,-1,sizeof(dp)); ten[0] = 1; for(int i=1;i<20;i++) ten[i] = (ten[i-1] * 10) % mod; } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); #endif init(); while(~scanf("%lld%lld%d",&l,&r,&k)) { cout<<(solve(r)-solve(l-1)+mod)%mod<<'\n'; } return 0; }
描述
给定一个数 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 |
样例输入