吉哥系列故事——恨7不成妻(数位DP)
吉哥系列故事——恨7不成妻
http://acm.hdu.edu.cn/showproblem.php?pid=4507
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 6974 Accepted Submission(s): 2279
Problem Description
单身!
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
依然单身!
吉哥依然单身!
DS级码农吉哥依然单身!
所以,他生平最恨情人节,不管是214还是77,他都讨厌!
吉哥观察了214和77这两个数,发现:
2+1+4=7
7+7=7*2
77=7*11
最终,他发现原来这一切归根到底都是因为和7有关!所以,他现在甚至讨厌一切和7有关的数!
什么样的数和7有关呢?
如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
现在问题来了:吉哥想知道在一定区间内和7无关的数字的平方和。
Input
输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
Output
请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。
Sample Input
3
1 9
10 11
17 17
Sample Output
236
221
0
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define lson l,mid,rt<<1 4 #define rson mid+1,r,rt<<1|1 5 #define sqr(x) ((x)*(x)) 6 #define pb push_back 7 #define eb emplace_back 8 #define maxn 100005 9 #define eps 1e-8 10 #define pi acos(-1.0) 11 #define rep(k,i,j) for(int k=i;k<j;k++) 12 typedef long long ll; 13 typedef pair<int,int> pii; 14 typedef pair<long long,int>pli; 15 typedef pair<int,char> pic; 16 typedef pair<pair<int,string>,pii> ppp; 17 typedef unsigned long long ull; 18 const long long MOD=1e9+7; 19 /*#ifndef ONLINE_JUDGE 20 freopen("1.txt","r",stdin); 21 #endif */ 22 struct DP{ 23 ll cnt,sum,sqsum; 24 DP(ll a=0,ll b=0,ll c=0):cnt(a),sum(b),sqsum(c){} 25 }dp[25][7][7]; 26 int a[25]; 27 ll fac[25]; 28 29 DP dfs(int pos,int aa,int bb,bool limit){ 30 if(pos==-1) return DP(aa!=0&&bb!=0,0,0); 31 if(!limit&&dp[pos][aa][bb].cnt!=-1) return dp[pos][aa][bb]; 32 int up=limit?a[pos]:9; 33 DP ans; 34 for(int i=0;i<=up;i++){ 35 if(i!=7){ 36 DP tmp=dfs(pos-1,(aa+i)%7,(bb*10+i)%7,limit&&i==up); 37 ans.cnt=(ans.cnt+tmp.cnt)%MOD; 38 ans.sum=(ans.sum+(((fac[pos]*i)%MOD*tmp.cnt)%MOD)+tmp.sum)%MOD; 39 ans.sqsum=((ans.sqsum+tmp.sqsum+(2*fac[pos]*i)%MOD*tmp.sum)%MOD)%MOD; 40 ans.sqsum=(ans.sqsum+((i*fac[pos]*i%MOD)*fac[pos]%MOD*tmp.cnt)%MOD)%MOD; 41 } 42 } 43 if(!limit) dp[pos][aa][bb]=ans; 44 return ans; 45 } 46 47 ll solve(ll x){ 48 int pos=0; 49 while(x){ 50 a[pos++]=x%10; 51 x/=10; 52 } 53 DP ans=dfs(pos-1,0,0,1); 54 return ans.sqsum; 55 } 56 57 int main(){ 58 #ifndef ONLINE_JUDGE 59 // freopen("1.txt","r",stdin); 60 #endif 61 std::ios::sync_with_stdio(false); 62 fac[0]=1; 63 for(int i=1;i<20;i++) fac[i]=(fac[i-1]*10)%MOD; 64 for(int i=0;i<25;i++){ 65 for(int j=0;j<7;j++){ 66 for(int k=0;k<7;k++){ 67 dp[i][j][k].cnt=-1; 68 } 69 } 70 } 71 int t; 72 cin>>t; 73 ll n,m; 74 while(t--){ 75 cin>>n>>m; 76 ll ans=(solve(m)-solve(n-1)+MOD)%MOD; 77 cout<<ans<<endl; 78 } 79 }
posted on 2019-03-14 17:19 Fighting_sh 阅读(245) 评论(0) 编辑 收藏 举报