吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1459 Accepted Submission(s): 426
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 2210
搜索时需记录<个数,<和,平方和> >
dp的四维分别是当前位,每位和%7,数值%7,是否已经出现了7。
假如我们搜到了i位是x(i>=0),dfs剩下的位得到了一个答案tmp;
那么当前第i位的答案就是:
<sigma(tmp.个数),<sigma(tmp.和+tmp.个数*10^i*x),sigma(tmp.平方和+(10^i*x)^2*tmp.个数 + 2*tmp.和*(10^i*x))> >
/* *===================== *File Name:hdu4507.cpp *Author: qqspeed *Date: 2014年 07月 21日 星期一 12:38:21 CST *===================== */ #include <stdio.h> #include <string.h> #include <iostream> #include <string> #include <math.h> #include <queue> #include <stack> #include <map> #include <vector> #include <stdlib.h> #include <algorithm> using namespace std; typedef long long ll; #define rep(i,s,t) for(int i=s;i<t;i++) #define red(i,s,t) for(int i=s-1;i>=t;i--) #define ree(i,now) for(int i=head[now];i!=-1;i=edge[i].next) #define clr(a,v) memset(a,v,sizeof a) #define L t<<1 #define R t<<1|1 #define MID int mid=(l+r)>>1 #define lowbit(x) (x&(-x)) #define SQR(a) ((a)*(a)) inline int input(){ int ret=0;bool isN=0;char c=getchar(); while(c<'0' || c>'9'){ if(c=='-') isN=1; c=getchar(); } while(c>='0' && c<='9'){ ret=ret*10+c-'0'; c=getchar(); } return isN?-ret:ret; } inline void output(int x){ if(x<0){ putchar('-');x=-x; } int len=0,data[11]; while(x){ data[len++]=x%10;x/=10; } if(!len) data[len++]=0; while(len--) putchar(data[len]+48); putchar('\n'); } const ll mod=1000000007; const ll ivr=166666668; pair<ll,pair<ll,ll> > dp[20][7][7][2]; ll l,r; int t,bit[20],len; ll ten[20]; inline ll Pow(ll a,ll b){ ll d=1,t=a; while(b){ if(b&1) d=d*t%mod; b>>=1; t=t*t%mod; } return d; } inline ll Sum(ll n){ n%=mod; return (n)*((n+1)%mod)%mod*((2*n+1)%mod)%mod*ivr%mod; } inline pair<ll,pair<ll,ll> >dfs(int i,bool e,int st1,int st2,int st3){ if(i<0) return make_pair(st1==0 || st2==0 || st3==1,make_pair(0,0)); if(!e && dp[i][st1][st2][st3].first!=-1) return dp[i][st1][st2][st3]; int v=(e?bit[i]:9); pair<ll,pair<ll,ll> > ans,tmp; ans=make_pair(0,make_pair(0,0)); rep(j,0,v+1){ tmp=dfs(i-1,e&&(j==v),(st1+j)%7,(st2*10+j)%7,st3|(j==7)); ans.first = (ans.first+tmp.first)%mod; ans.second.first = (ans.second.first+tmp.second.first+ten[i]*j%mod*tmp.first)%mod; ans.second.second = (ans.second.second + tmp.second.second + ten[i]*j%mod*ten[i]%mod*j%mod*tmp.first%mod + 2*ten[i]*j%mod*tmp.second.first%mod)%mod; } if(!e) dp[i][st1][st2][st3]=ans; return ans; } inline ll solve(ll n){ ll sum=Sum(n); if(n<=0) return 0; len=0; while(n){ bit[len++]=n%10; n/=10; } return (sum-dfs(len-1,1,0,0,0).second.second+mod)%mod; } int main(){ rep(i,0,20) rep(j,0,7) rep(k,0,7) rep(r,0,2) dp[i][j][k][r]=make_pair(-1,make_pair(0,0)); ten[0]=1; rep(i,1,20) ten[i]=ten[i-1]*10%mod; t=input(); while(t--){ cin>>l>>r; cout<<(solve(r)-solve(l-1)+mod)%mod<<endl; } return 0; }