中文题,题意略,老年人康复练习
数位DP,
和一般的不同,这种数位dp统计数字和或者数字平方和
注意取模!!!
数位DP,
和一般的不同,这种数位dp统计数字和或者数字平方和
注意取模!!!
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[20];
const ll mod=1e9+7;
ll po[20];
struct D{
ll cnt,sum,sum2;
D(){}
D(ll a ,ll b,ll c){cnt=a%mod,sum=b%mod,sum2=c%mod;};
};
D dp[20][10][10];
inline ll add(ll a,ll b){
return (a+b)%mod;
}
inline ll mul(ll a,ll b){
return (a*b)%mod;
}
D dfs(int pos,ll sum,ll eve,bool limit){
if(pos==-1&&eve!=0&&sum!=0) return D(1,0,0);
if(pos==-1) return D(0,0,0);
if(!limit && dp[pos][sum][eve].cnt!=-1) return dp[pos][sum][eve];
int up=limit?a[pos]:9;
D ans=D(0,0,0);
for(ll i=0;i<=up;i++){
if(i==7) continue;
D t=dfs(pos-1,(sum*10+i)%7,(eve+i)%7,limit && i==a[pos]);
ans=D(add(ans.cnt,t.cnt),
add(ans.sum,add(t.sum,mul(mul(po[pos],i),t.cnt))),
add(add(add(t.sum2, mul(mul(mul(i, po[pos]),mul(i, po[pos])),t.cnt)), mul(mul(2*i,po[pos]), t.sum)), ans.sum2)
);
}
if(!limit) dp[pos][sum][eve]=ans;
return ans;
}
D solve(ll x){
int pos=0;
while(x){
a[pos++]=x%10;
x/=10;
}
return dfs(pos-1,0,0,true);
}
int main(){
memset(dp,-1,sizeof(dp));
po[0]=1;
for(int i=1;i<20;i++) po[i]=(po[i-1]*10LL)%mod;
ll le,ri;
int t;
cin>>t;
while(t--){
scanf("%lld%lld",&le,&ri);
printf("%lld\n",(solve(ri).sum2-solve(le-1).sum2+mod)%mod);
}
}