吉哥系列故事——恨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无关的数字的平方和。
 

 

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 }
View Code

 

posted on 2019-03-14 17:19  Fighting_sh  阅读(243)  评论(0编辑  收藏  举报

导航