#1033 : 交错和
时间限制: 10000ms
单点时限:
1000ms
内存限制:
256MB
-
100 121 0
样例输出
-
231
看其他人的思路多是dfs求解,不过我用的是非递归的方式,而是先求出不同位上不同交错和的结果,再根据给定的范围[l,r],求出ans(r+1)-ans(l),即为最后的结果。过程相对dfs比较复杂,所以写加调试花了一下午加晚上。。。,sum[n][k+100],记录n位数交错和为k的结果,flagh[n][k+100],保存的是对应的结果中包含的数的个数。其中用了二分法求两个数的相乘以防越界
#include <iostream> #include<stdio.h> typedef long long ll; #define MOD 1000000007 using namespace std; ll sumh[19][210]= {{0}},flagh[19][210]= {{0}}; ll multiply( ll a,ll b) { if(a==1) return b%MOD; else { ll des=0,ans=b%MOD; while(a>0) { if(a%2>0) des=(des+ans)%MOD; ans=(ans+ans)%MOD; a/=2; } return des; } } void init() { int i,j; for(i=0; i<10; i++ ) { sumh[1][i+100]=i; flagh[1][i+100]=1; } sumh[0][100]=0; flagh[0][100]=1; ll tig=10; for(i=2; i<=18; i++) { for(j=1; j<=9; j++) { for(int g=1; g<i; g++) { int flag=(i-g)%2>0?-1:1; ll ad1=(tig*j)%MOD; for(int k=-(g/2+1)*9; k<=(g/2+1)*9; k++) { if(flagh[g][k+100]>0) { int j2=j+k*flag+100; ll s2=multiply(flagh[g][k+100],ad1); sumh[i][j2]=(s2+sumh[g][k+100]+ sumh[i][j2])%MOD; flagh[i][j2]=(flagh[g][k+100]+flagh[i][j2])%MOD; } } } } tig*=10; } } int change(ll a,int *num) { int l=0; while(a>0) { num[l++]=a%10; a/=10; } return l; } ll countn(ll a,int k) { int num[20]= {0}; int l=change(a,num); ll ans=0; for(int i=l-1; i>=1; i--) { if(flagh[i][k+100]>0) ans=(ans+sumh[i][k+100])%MOD; } ll tig=1; for(int i=1; i<=l-1; i++) { tig*=10; } int ad=0; ll jtig=0; for(int i=l-1; i>=0; i--) { int flag=1; if((l-1-i)%2) flag=-1; for(int j=0; j<num[i] ; j++) { if(j==0&&i<l-1||j>0) { int ad1 =ad+flag*j; int k3=(k-ad1); for(int g=i; g>=0; g--) { if(g>0||i==0) { int k2=k3; if((l-g)%2==1) k2=k2*-1; k2=k2+100; if(flagh[g][k2]>0) { ans=(ans+sumh[g][k2])%MOD; ll s2=multiply(flagh[g][k2],jtig+j*tig); ans=(ans+s2)%MOD; } } } } } ad =ad+flag*num[i]; jtig+=num[i]*tig; tig/=10; } return ans; } int main() { ll a,b; int k; init(); scanf("%lld%lld%d",&a,&b,&k); ll ansa=countn(a,k);//printf("%lld\n",ansa); ll ansb=countn(b+1,k)+MOD;//printf("%lld\n",ansb); printf("%lld\n",(ansb-ansa)%MOD);//test(b,k); 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(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 |