吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1964 Accepted Submission(s): 569
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
[L,R]内所有满足条件的数的平方和是多少。
这题有点。。重点在于怎么求平方和。
维护的dp值不止一个,要维护3个,dp[cur][sum1][sum2]里的a,a2,n。表示当前处理到cur位置,前面的数mod7=sum1,前面的数位和mod7=sum2,这个状态下后面所有满足的取值、后面这些位的和为a,平方和为a2,共有n个数。可以根据a,a2,n推出当前的a',a2',n',相当于已知a1+..+an,a1^2+..+an^2,求(a1+b)^2+(a2+b)^2..+(an+b)^2。若当前这一位取i,a'+=i*10^cur*n+a,a2'+=(10^cur)^2*i^2*n+2*10^cur*i*a+a2,n'+=n。
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MAXN=70;
const LL MOD=1000000007;
int T;
LL L,R;
int bit[MAXN];
bool vis[MAXN][10][10];
LL power[20];
struct DP{
LL a,a2,n;
}dp[MAXN][10][10];
DP dfs(int cur,int sum1,int sum2,int e){
if(cur<0){
if(sum1%7&&sum2%7) return (DP){0,0,1};
return (DP){0,0,0};
}
if(!e&&vis[cur][sum1][sum2]) return dp[cur][sum1][sum2];
int end=e?bit[cur]:9;
LL b=0,b2=0,n=0;
DP tmp;
for(int i=0;i<=end;i++) if(i!=7){
tmp=dfs(cur-1,(sum1*10+i)%7,(sum2+i)%7,e&&i==end);
if(tmp.n>0){
b=(b+(i*power[cur])%MOD*tmp.n%MOD+tmp.a)%MOD;
b2=(b2+((power[cur]*power[cur]%MOD*i*i)%MOD*tmp.n%MOD+(2*power[cur]*i%MOD*tmp.a)%MOD+tmp.a2)%MOD)%MOD;
n=(n+tmp.n)%MOD;
}
}
if(!e){
vis[cur][sum1][sum2]=1;
dp[cur][sum1][sum2]=(DP){b,b2,n};
}
return (DP){b,b2,n};
}
LL solve(LL n){
int len=0;
while(n){
bit[len++]=n%10;
n/=10;
}
return dfs(len-1,0,0,1).a2;
}
int main(){
freopen("in.txt","r",stdin);
scanf("%d",&T);
power[0]=1;
for(int i=1;i<=18;i++) power[i]=(power[i-1]*10)%MOD;
memset(vis,0,sizeof(vis));
while(T--){
scanf("%I64d%I64d",&L,&R);
printf("%I64d\n",(solve(R)-solve(L-1)+MOD)%MOD);
}
return 0;
}