HDU - 4507 吉哥系列故事——恨7不成妻

Discription
  单身! 
  依然单身! 
  吉哥依然单身! 
  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


直接暴力数位dp,设f[i][j][k][u][v]为考虑了前i位,每一位的和%7==j,前i位构成的数%7==k,是否贴上界的情况为u的所有数的v次方和。
转移的时候考虑全情况一般就没问题了hhh,不过情况有点多,最好列一下。。。。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int ha=1000000007;
int f[25][7][7][2][3],T,n,a[25],ans;
ll L,R,Y;
inline int add(int x,int y){ x+=y; return x>=ha?x-ha:x;}
inline void ADD(int &x,int y){ x+=y; if(x>=ha) x-=ha;}
inline G(int x,int y){ return (x+y)%7;}
inline int solve(ll x){
	memset(f,0,sizeof(f)),n=0;
	Y=x; while(Y) a[++n]=Y%10,Y/=10;
	reverse(a+1,a+n+1),ans=0;
	
	f[0][0][0][1][0]=1;
	for(int i=0;i<n;i++)
	    for(int j=0;j<7;j++)
	        for(int k=0;k<7;k++)
	            for(int num=0,TX,TY;num<10;num++) if(num!=7){
	            	TX=G(j,num),TY=G(k*10%7,num);
	            	ADD(f[i+1][TX][TY][0][0],f[i][j][k][0][0]);
	            	ADD(f[i+1][TX][TY][0][1],add(f[i][j][k][0][1]*10ll%ha,f[i][j][k][0][0]*(ll)num%ha));
	            	ADD(f[i+1][TX][TY][0][2],add(f[i][j][k][0][2]*100ll%ha,f[i][j][k][0][1]*(ll)(20ll*num)%ha));
	            	ADD(f[i+1][TX][TY][0][2],f[i][j][k][0][0]*(ll)(num*num)%ha);
                    if(num<a[i+1]){
    	            	ADD(f[i+1][TX][TY][0][0],f[i][j][k][1][0]);
	            	    ADD(f[i+1][TX][TY][0][1],add(f[i][j][k][1][1]*10ll%ha,f[i][j][k][1][0]*(ll)num%ha));
	            	    ADD(f[i+1][TX][TY][0][2],add(f[i][j][k][1][2]*100ll%ha,f[i][j][k][1][1]*(ll)(20ll*num)%ha));
	            	    ADD(f[i+1][TX][TY][0][2],f[i][j][k][1][0]*(ll)(num*num)%ha);                	
					}
					else if(num==a[i+1]){
    	            	ADD(f[i+1][TX][TY][1][0],f[i][j][k][1][0]);
	            	    ADD(f[i+1][TX][TY][1][1],add(f[i][j][k][1][1]*10ll%ha,f[i][j][k][1][0]*(ll)num%ha));
	            	    ADD(f[i+1][TX][TY][1][2],add(f[i][j][k][1][2]*100ll%ha,f[i][j][k][1][1]*(ll)(20ll*num)%ha));
	            	    ADD(f[i+1][TX][TY][1][2],f[i][j][k][1][0]*(ll)(num*num)%ha);     						
					}
			    }
	
	for(int i=1;i<7;i++)
	    for(int j=1;j<7;j++)
		    for(int l=0;l<=1;l++) ans=add(ans,f[n][i][j][l][2]);
	
	return ans;
}

int main(){
	scanf("%d",&T);
	while(T--) scanf("%lld%lld",&L,&R),printf("%d\n",add(solve(R),ha-solve(L-1)));
	return 0;
}

  

 

猜你喜欢

转载自www.cnblogs.com/JYYHH/p/8931891.html