http://acm.hdu.edu.cn/showproblem.php?pid=5435
Problem Description
Xiao Jun likes math and he has a serious math question for you to finish.
Define F[x] to the xor sum of all digits of x under the decimal system,for example F(1234) = 1 xor 2 xor 3 xor 4 = 4 .
Two numbers a,b(a≤b) are given,figure out the answer of F[a] + F[a+1] + F[a+2]+…+ F[b−2] + F[b−1] + F[b] doing a modulo 109+7 .
Define F[x] to the xor sum of all digits of x under the decimal system,for example F(1234) = 1 xor 2 xor 3 xor 4 = 4 .
Two numbers a,b(a≤b) are given,figure out the answer of F[a] + F[a+1] + F[a+2]+…+ F[b−2] + F[b−1] + F[b] doing a modulo 109+7 .
Input
The first line of the input is a single integer
T(T<26)
, indicating the number of testcases.
Then T testcases follow.In each testcase print three lines :
The first line contains one integers a .
The second line contains one integers b .
1≤|a|,|b|≤100001 , |a| means the length of a .
Then T testcases follow.In each testcase print three lines :
The first line contains one integers a .
The second line contains one integers b .
1≤|a|,|b|≤100001 , |a| means the length of a .
Output
For each test case, output one line "Case #x: y", where
x
is the case number (starting from 1) and
y
is the answer.
Sample Input
4 0 1 2 2 1 10 9999 99999
Sample Output
Case #1: 1 Case #2: 2 Case #3: 46 Case #4: 649032
/**
hdu5435 数位dp(大数的处理)
题目大意:一个数字的值为它各个位上数字异或的结果,给定两个数,问二者闭区间内有所有数字值得和为多少?
解题思路:我用的是记忆话搜索的写法,好像递归耗时比较多吧,比赛时过了,后来给判掉了,最后老是TLE。
网上学的方法: dp[i][j][k]表示前i位数(k==0||k==1)异或值为j的数有多少个,k为0则表示到结尾了,1表示没有到结尾
最后注意分别取模会TLE,具体看代码怎么实现的吧
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const int maxn=100005;
const LL mod=1e9+7;
char s1[maxn],s2[maxn];
int bit[maxn];
LL dp[maxn][16][2];
LL solve(char *a)
{
int n=strlen(a);
for(int i=1; i<=n; i++)bit[i]=a[i-1]-'0';
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;
for(int i=0; i<n; i++)
{
int num=bit[i+1];
for(int j=0; j<16; j++)
{
dp[i][j][0]%=mod;
dp[i][j][1]%=mod;
if(dp[i][j][0]>0)
{
dp[i+1][j^num][0]+=dp[i][j][0];
for(int k=0; k<num; k++)
{
dp[i+1][j^k][1]+=dp[i][j][0];
}
}
if(dp[i][j][1]>0)
{
for(int k=0; k<=9; k++)
{
dp[i+1][j^k][1]+=dp[i][j][1];
}
}
}
}
LL ans=0;
for(int i=1; i<=15; i++)
{
ans+=(dp[n][i][0]+dp[n][i][1])*(LL)i;
ans%=mod;
}
ans%=mod;
return ans;
}
int main()
{
int T,tt=0;
scanf("%d",&T);
while(T--)
{
scanf("%s%s",s1,s2);
int n=strlen(s1);
LL ans=s1[0]-'0';
for(int i=1; i<n; i++)
ans^=(s1[i]-'0');
printf("Case #%d: %I64d\n",++tt,(solve(s2)-solve(s1)+ans+mod)%mod);
}
return 0;
}