吉哥系列故事——恨7不成妻
Time Limit: 1000/500 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1154 Accepted Submission(s): 343
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
Source
Recommend
Statistic | Submit | Discuss | Note
最近在练习数位dp,觉得自己很水很菜,就这道题我做了三天!!
其实如果是求个数有多少,相信很多人都会做。。因为这就是很简单的数位dp
但是它加了求平方和。。如果你是在平时的基础上改一下就会错了。。
主要是求平方和:
(tem+B1)^2 + (tem+B2)^2 + (tem+B3)^2 + ……(tem+Bn)^2 = tem^2*n + 2*tem(B1+B2+……Bn) + (B1^2 +B2^2+……+Bn^2)
这里的意思是假如有一个数 9535425471 DFS到2时 那其实我们是想求以2开头的5位数满足
情况的平方和,所以tem就为20000,而Bi就是递归下去找和20000匹配且满足要求的平方和
就是上面这一条公式了
#include<stdio.h>
#include<string.h>
const __int64 MOD = 1e9+7;
typedef struct node
{
__int64 nn;
__int64 sum,sqsum;
int flag;
};
node dp[31][10][10][3];
__int64 l,r;
__int64 po[22];
int m[22];
void Init()
{
int i,k,j,r;
po[0] = 1;
for(i=1;i<22;i++)
po[i] = (10*po[i-1])%MOD;
for(i=0;i<30;i++)
for(j=0;j<10;j++)
for(k=0;k<10;k++)
for(r=0;r<3;r++)
{
dp[i][j][k][r].nn = dp[i][j][k][r].sum = dp[i][j][k][r].sqsum =dp[i][j][k][r].flag=0;
}
}
int tran(__int64 p)
{
memset(m,0,sizeof(m));
int b = 1;
while(p)
{
m[b++] = p%10;
p = p/10;
}
return b-1;
}
node DFS(int len,int flag1,int f,int p,int doing)//flag1是否有7,f后面的数之和
{ //p后面的数平方之和
node kk;
kk.flag = kk.nn = kk.sqsum = kk.sum = 0;
if(len==0)
{
if(!flag1 && f!=0 && p!=0)
{
kk.nn = 1;
return kk;
}
else
return kk;
}
if(!doing && dp[len][f][p][flag1].flag)
return dp[len][f][p][flag1];
int end = doing?m[len]:9;
node var1,var2;
var1.sum = var1.sqsum = var1.nn = var1.flag = 0;
var2.sum = var2.sqsum = var2.nn = var2.flag = 0;
for(int i=0;i<=end;i++)
{
var1 = DFS(len-1,i==7?1:flag1,(f+i)%7,(p*10+i)%7,doing&&(i==end));
__int64 tem = (i*po[len-1])%MOD;
var2.nn = (var1.nn+var2.nn)%MOD;
var2.sum = (tem*var1.nn%MOD+var1.sum+var2.sum)%MOD;
var2.sqsum = ( ((tem*tem)%MOD*var1.nn)%MOD + (2*tem*var1.sum)%MOD + var1.sqsum +var2.sqsum )%MOD;
}
if(!doing)
{
var2.flag = 1;
dp[len][f][p][flag1] = var2;
}
return var2;
}
int main()
{
int t;
Init();
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&l,&r);
__int64 ll = DFS(tran(l-1),0,0,0,1).sqsum;
__int64 rr = DFS(tran(r),0,0,0,1).sqsum;
printf("%I64d\n",(rr-ll+MOD)%MOD);
}
return 0;
}