版权声明:欢迎转载(标记出处),写得不好还请多指教 https://blog.csdn.net/quan_tum/article/details/82146515
这一题的题目描述很…无法描述,但还是能马上看出是一道数位dp题。限制的条件有点多,细节处理起来确实很烦。只要记录合法的数的个数,数的和以及数的平方和。
#include<bits/stdc++.h>
#define ll long long
#define il inline
using namespace std;
const int mo=1e9+7;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il ll read(){
ll x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(ll x){
if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
struct A{
ll s0,s1,s2;
A(){}
A(ll a,ll b,ll c):s0(a),s1(b),s2(c){}
}f[20][7][7];
ll c[20],d[20],T,l,r;
il A dfs(int l,int s,int ss,bool o){
if(l<0) return A(s&&ss,0,0);
if(!o&&f[l][s][ss].s0!=-1) return f[l][s][ss];
int r=o?d[l]:9;
A ans=A(0,0,0);
for(int i=0;i<=r;++i){
if(i!=7){
A t=dfs(l-1,(s+i)%7,(ss*10+i)%7,o&&i==r);
(ans.s0+=t.s0)%=mo;
(ans.s1+=(c[l]*i%mo*t.s0%mo+t.s1)%mo)%=mo;
(ans.s2+=(t.s2+2*c[l]*i%mo*t.s1%mo)%mo)%=mo;
(ans.s2+=i*c[l]*i%mo*c[l]%mo*t.s0%mo)%=mo;
}
}
if(!o) f[l][s][ss]=ans;
return ans;
}
void init(){
c[0]=1;
for(int i=1;i<20;++i)
c[i]=(c[i-1]*10)%mo;
}
il ll solve(ll x){
int l=0;
while(x){d[l++]=x%10;x/=10;}
A ans=dfs(l-1,0,0,1);
return ans.s2;
}
int main(){
init();T=read();
memset(f,-1,sizeof(f));
while(T--){
l=read(),r=read();
print((solve(r)-solve(l-1)+mo)%mo);
}Ot();return 0;
}