1033 : 交错和
时间限制: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,求在 [l, r] 区间中,所有 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 <cstdio>
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <string>
#include <cstring>
using namespace std;
#define LL long long
const int maxn = 100;
const int mod = 1e9 + 7;
int a[maxn];
struct p
{
LL sum,cnt;
p (LL a = -1,LL b = 0)
{
this -> sum = a;
this -> sum = b;
}
}dp[20][400][2][2][2][10];
LL ba[20];
p dfs(int pos,int sum,int k,int limit,int tar,int lead,int d)
{
if (pos == -1)
{
p tmp;
tmp.cnt = 0;
tmp.sum = -2;
if (sum == k)
{
tmp.cnt = 1;
tmp.sum = d;
return tmp;
}
return tmp;
}
if (dp[pos][sum + 200][limit][tar][lead][d].sum != -1) return dp[pos][sum + 200][limit][tar][lead][d];
LL ans = 0;
int up = limit ? a[pos] : 9;
p t;
int f;
f = 0;
int tot = 0;
int flag = 0;
for (int i = 0; i <= up; i++){
if (tar == 0)
{
t = dfs(pos - 1,sum - i,k,limit && a[pos] == i,tar ^ 1,lead,i);
}else
{
if (lead)
{
if (i != 0) t = dfs(pos - 1,sum + i,k,limit && a[pos] == i, tar ^ 1, lead ^ 1,i);
else t = dfs(pos - 1,sum + i,k,limit && a[pos] == i,tar,lead,i);
}else
{
t = dfs(pos - 1,sum + i,k,limit && a[pos] == i,tar ^ 1,lead,i);
}
}
if (t.sum != -2)
{
flag = 1;
ans += t.sum;
ans %= mod;
tot += t.cnt;
tot %= mod;
if (pos != 0) f = (f + i * (t.cnt % mod)) % mod;
}
}
ans = f * ba[pos] + ans;
ans %= mod;
p now;
now.sum = ans;
now.cnt = tot;
now.cnt %= mod;
if (!flag) now.sum = -2;
if (!limit) dp[pos][sum + 200][limit][tar][lead][d] = now;
return now;
}
p solve(LL x,int k)
{
LL tmp = x;
int pos = 0;
while (tmp){
a[pos++] = tmp % 10;
tmp /= 10;
}
return dfs(pos - 1,0,k,1,1,1,0);
}
void init(){
for (int i = 0; i < 20; i++){
for (int j = 0; j < 400; j++){
for (int k = 0; k < 2; k++){
for (int u = 0; u < 2; u++){
for (int v = 0; v < 2; v++){
for (int o = 0; o < 10; o++){
dp[i][j][k][u][v][o].sum = -1;
dp[i][j][k][u][v][o].cnt = 0;
}
}
}
}
}
}
}
int main(){
LL l,r,k;
ba[0] = 1;
for (int i = 1; i <=18; i++) ba[i] = ba[i - 1] * 10 % mod;
init();
cin >> l >> r >> k;
LL L = solve(l - 1,k).sum;
LL R = solve(r, k).sum;
printf("%lld\n",(((R == -2 ? 0 : R)- (L == -2 ? 0 : L)) % mod + mod) % mod);
}