hdu 4507 恨7不成妻(求l,r中与7不相关数字的平方和)
吉哥他生平最恨情人节,不管是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无关的数字的平方和。
解题思路:
如果确定了一个数字x,然后确定要在最高位添加一个i的数字,那么此时该数字等于
(10^X的位数)*i+x;
我们设这个数字为f=(10^X的位数)*I;那么现在这个数字的平方就变成了(f+x)^2=f^2+x^2+2*f*x;
那么此时转化一下就OK了。
Dp[i][j][k][y]i表示当前数字的位数,j表示是否存在7,k表示数字每个数位之和%7,y表示该数字%7。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #define MOD 1000000007 6 typedef long long LL; 7 int const N = 20; 8 LL l,r,pow10[N]; 9 int bit[N],t; 10 struct node 11 { 12 LL co,x,fx; 13 }dp[N][2][7][7]; 14 void pre() 15 { 16 pow10[0]=1; 17 for(int i=1;i<20;i++)pow10[i]=(pow10[i-1]*10)%MOD; 18 for(int i=0;i<20;i++) 19 for(int j=0;j<2;j++) 20 for(int k=0;k<7;k++) 21 for(int y=0;y<7;y++) 22 dp[i][j][k][y].co=-1; 23 } 24 LL getsum1(LL n) 25 { 26 LL num1=n,num2=n+1,num3=(2*n+1); 27 if(num1%2==0)num1/=2; 28 else num2/=2; 29 if(num3%3==0)num3/=3; 30 else 31 if(num2%3==0)num2/=3; 32 else 33 if(num1%3==0)num1/=3; 34 num1=num1%MOD,num2=num2%MOD,num3=num3%MOD; 35 return (((num1*num2)%MOD)*num3)%MOD; 36 } 37 node getsum2(int len,int ad,int re1,int re2,int lim) 38 { 39 if(dp[len][ad][re1][re2].co!=-1&&!lim) 40 return dp[len][ad][re1][re2]; 41 if(!len) 42 { 43 if(ad||!re1||!re2)dp[len][ad][re1][re2].co=1LL; 44 else dp[len][ad][re1][re2].co=0LL; 45 dp[len][ad][re1][re2].x=dp[len][ad][re1][re2].fx=0LL; 46 return dp[len][ad][re1][re2]; 47 } 48 int up=(lim)?bit[len]:9; 49 LL tco=0LL,tx2=0LL,tfx=0LL; 50 for(int i=0;i<=up;i++) 51 { 52 int nad=(i==7||ad),nre1=(re1+i)%7,nre2=(re2*10+i)%7; 53 LL f=(i*pow10[len-1])%MOD; 54 node tmp=getsum2(len-1,nad,nre1,nre2,lim&&(i==up)); 55 tx2=(tx2+tmp.x+f*tmp.co)%MOD; 56 tfx=(tfx+tmp.fx+tmp.co*((f*f)%MOD)+2*f*tmp.x)%MOD; 57 tco=(tco+tmp.co)%MOD; 58 } 59 if(!lim) 60 { 61 dp[len][ad][re1][re2].co=tco; 62 dp[len][ad][re1][re2].x=tx2; 63 dp[len][ad][re1][re2].fx=tfx; 64 } 65 node tmp; 66 tmp.co=tco; 67 tmp.x=tx2; 68 tmp.fx=tfx; 69 return tmp; 70 } 71 LL getsum3(LL n) 72 { 73 LL num=n; 74 t=0; 75 for(;num;num/=10)bit[++t]=num%10; 76 LL sum=getsum1(n); 77 return (sum-getsum2(t,0,0,0,1).fx)%MOD; 78 } 79 int main() 80 { 81 int T; 82 scanf("%d",&T); 83 pre(); 84 while(T--) 85 { 86 scanf("%I64d %I64d",&l,&r); 87 printf("%I64d\n",((getsum3(r)-getsum3(l-1))%MOD+MOD)%MOD); 88 } 89 return 0; 90 }