51nod 1607-卷积和(数位DP)

来源:互联网 发布:测试耳机的软件 编辑:程序博客网 时间:2024/06/07 14:39
1607 卷积和
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
 收藏
 关注

杰西最近在研究卷积,例如一个数字1234,那么经过杰西的变换后,就会变成1*4+2*3+3*2+4*1,例如一个数字是234,那么就会变成2*4+3*3+4*2。

形象化的,我们可以设f(x)表示x经过杰西变换后的值。用公式表示 x=dn1dn2...d2d1d0 那么 f(x)=n1i=0didn1i 

例如f(1234)=20,f(234)=25。

现在他想到了一个问题。

如果他想知道对于所有i=L~R时的f(i)的值的和,该怎么做呢。

现在这个问题交给了你。

但是这个答案可能会非常大,因此杰西只想知道最终答案对1000000007取模后的答案。


Input
单组测试数据一行两个整数L,R(1<=L<=R<=10^18)。
Output
一个数表示答案。
Input示例
3 233
Output示例
8730
System Message (题目提供者)
C++的运行时限为:1000 ms ,空间限制为:131072 KB 示例及语言说明请按这里

 允许其他 AC 的用户查看此代码,分享代码才能查看别人的代码并有机会获得勋章


感觉是一道比较烦的数位DP,情况比较多,看了题解看了很久才看明白23333,然后自己对着码了一遍,算是理解透彻了。。。比较难写,代码中加了一些注释。。。


#include<map>   #include<stack>          #include<queue>          #include<vector>          #include<math.h>          #include<stdio.h>          #include<iostream>          #include<string.h>          #include<stdlib.h>  #include<algorithm> #include<functional>  using namespace std;          typedef long long  ll;         #define inf  1000000000     #define mod 1000000007           #define maxn  1000005#define lowbit(x) (x&-x)          #define eps 1e-9ll digit[25],q[25];void init(){q[1]=1;for(int i=2;i<=20;i++)q[i]=q[i-1]*10%mod;}ll dp(ll x,int a,int b,int v){ll res=0;int i,j,len=a+b-1;if(v==0){if(a==1)return q[a+b-2]*2025%mod;elsereturn q[a+b-3]*9*2025%mod;}else//类似奇数位求贡献的方法,注意细节{for(i=len;i>b;i--)res=(res+(digit[i]-(i==len))*2025*q[i-2]%mod)%mod;for(i=1;i<digit[b];i++)res=(res+q[b-1]*45*i%mod)%mod;for(i=b-1;i>a;i--)res=(res+digit[i]*q[i-1]*digit[b]*45%mod)%mod;for(i=1;i<digit[a];i++)res=(res+q[a]*digit[b]*i%mod)%mod;res=(res+(x%q[a]+1)*digit[a]*digit[b]%mod)%mod;}return res;}ll solve(ll x){if(x<1) return 0;int i,j,len=0;ll tmp=x,res=0;while(tmp){digit[++len]=tmp%10;tmp/=10;}for(i=1;i<=len;i++){if(2*i-1>len)break;if(2*i-1<len)//位数小于上限时中间位的总贡献{if(i==1)res=(res+285)%mod;elseres=(res+q[2*i-2]*9*285%mod)%mod;}if(2*i-1==len){for(j=len;j>i;j--)//计算比中间位高的位数上的数发生变化时的贡献res=(res+(digit[j]-(j==len))*285*q[j-1]%mod)%mod;for(j=1;j<digit[i];j++)//高位不变,中间位变化时的贡献res=(res+q[i]*j*j%mod)%mod;res=(res+digit[i]*digit[i]*(x%q[i]+1)%mod)%mod;//仅低位变化时的贡献}}for(i=1;i<=len;i++)//计算成对卷积和for(j=i+1;j<=len;j++){if(i+j-1>len)break;res=(res+2*dp(x,i,j,i+j-1==len)%mod)%mod;}return res;}int main(void){init();ll l,r;while(scanf("%lld%lld",&l,&r)!=EOF){printf("%lld\n",(solve(r)-solve(l-1)+mod)%mod);}return 0;}



原创粉丝点击