hdu 4507 吉哥系列故事——恨7不成妻 [按位dp]

             zzy 2013.3.22@科A232

 

  题目地址http://acm.hdu.edu.cn/showproblem.php?pid=4507 

  题目描述:求一个区间[L, R]中和7无关的数的平方和,和7无关的数定义为同时不满足下面三点:

  1.各位数字不包含7;

  2.各位数字之和不是7的倍数;

  3.这个整数不是7的倍数。

  解题思路:典型的按位dp。一开始想会不会是数学结论题,但是很快觉得数学一点不靠谱,然后发现按位dp可做。

  我的做法是求出区间[0, N]中满足条件的数的平方和,这样可以不用卡下界。

  定义数组dp[ d ][ u ][ i ][ j ],d表示dp到第d位,u表示是否卡上界(按惯例,0表示卡上界),i表示前缀的各位数字和模7为i,j表示前缀表示的整数模7为j。每个元素存num、sum、ssum三个值。num表示满足条件的前缀数量,sum则是这些前缀表示的整数的和,ssum是这些前缀表示的整数的平方和。

  dp从最高位到最低位枚举p,再枚举当前位的数字d,并枚举上一位p+1位的dp数组最后两维i:0~6,j:0~6。计算出转移到p位时的余数值:

  ii = (i + d)%7     jj = (j * 10 + d)%7

  最基本的转移方程是:

  dp[ p ][ 1 ][ ii ][ jj ].num += dp[ p + 1][ 1 ][ i ][ j ];

  dp[ p ][ 1 ][ ii ][ jj ].sum += dp[ p + 1 ][ 1 ][ i ][ j ].sum * 10 

        + dp[ p + 1 ][ 1 ][ i ][ j ].num * d;

  dp[ p ][ 1 ][ ii ][ jj ].ssum += dp[ p + 1 ][ 1 ][ i ][ j ].ssum * 100 

        + dp[ p + 1 ][ 1 ][ i ][ j ].sum * 20 * d 

        + d * d * dp[ p + 1 ][ 1 ][ i ][ j ].num;

再注意考虑哈上界问题就行了。

 

源代码

  1 //zzy.2013.3.21AC
  2 #include<cstdio>
  3 #include<iostream>
  4 #include<algorithm>
  5 
  6 using namespace std;
  7 
  8 #define ll long long
  9 #define MOD (1000000007LL)
 10 
 11 typedef struct
 12 {
 13     ll num,sum,ssum;
 14 }node;
 15 
 16 ll digits[21];
 17 node dp[21][2][7][7];
 18 
 19 void ini(ll len)
 20 {
 21     for(ll i = 1; i <= len + 1; ++i){
 22         for(ll j = 0; j < 2; ++j){
 23             for(ll k = 0; k < 7; ++k){
 24                 for(ll m = 0; m < 7; ++m){
 25                     dp[i][j][k][m].num = 0;
 26                     dp[i][j][k][m].sum = 0;
 27                     dp[i][j][k][m].ssum = 0;
 28                 }
 29             }
 30         }
 31     }
 32 }
 33 
 34 ll Len(ll N)
 35 {
 36     ll ret = 0;
 37     while(N){
 38         ret ++;
 39         digits[ret] = N % 10;
 40         N = N / 10;
 41     }
 42     return ret;
 43 }
 44 
 45 void DP(ll len)
 46 {
 47     for(ll p = len; p > 0; p--)
 48     {
 49         for(ll d = 0; d <= 9; d++)
 50         {
 51             if(d == 7) continue;
 52             for(ll i=0; i<7; i++)
 53             {
 54                 for(ll j=0; j<7; j++)
 55                 {
 56                     ll ii,jj;
 57                     ii = (i+d)%7;
 58                     jj = (j*10+d)%7;
 59                     dp[p][1][ii][jj].sum += dp[p+1][1][i][j].sum*10 
+ dp[p+1][1][i][j].num*d; 60 if(d < digits[p]) 61 dp[p][1][ii][jj].sum += dp[p+1][0][i][j].sum*10
+ dp[p+1][0][i][j].num*d; 62 dp[p][1][ii][jj].sum %= MOD; 63 64 dp[p][1][ii][jj].num += dp[p+1][1][i][j].num; 65 if(d < digits[p]) 66 dp[p][1][ii][jj].num += dp[p+1][0][i][j].num; 67 dp[p][1][ii][jj].num %= MOD; 68 69 dp[p][1][ii][jj].ssum += dp[p+1][1][i][j].ssum * 100LL
+ 20LL * d * dp[p+1][1][i][j].sum + d*d * dp[p+1][1][i][j].num; 70 if(d < digits[p]) 71 dp[p][1][ii][jj].ssum += dp[p+1][0][i][j].ssum * 100LL
+ 20LL * d * dp[p+1][0][i][j].sum + d*d * dp[p+1][0][i][j].num; 72 dp[p][1][ii][jj].ssum %= MOD; 73 } 74 } 75 } 76 ll d = digits[p]; 77 if(d == 7) continue; 78 for(ll i=0; i<7; i++) 79 { 80 for(ll j=0; j<7; j++)if(dp[p+1][0][i][j].num) 81 { 82 ll ii,jj; 83 ii = (i+d)%7; 84 jj = (j*10+d)%7; 85 dp[p][0][ii][jj].sum += dp[p+1][0][i][j].sum*10 + dp[p+1][0][i][j].num*d; 86 dp[p][0][ii][jj].sum %= MOD; 87 88 dp[p][0][ii][jj].num += dp[p+1][0][i][j].num; 89 dp[p][0][ii][jj].num %= MOD; 90 91 dp[p][0][ii][jj].ssum += dp[p+1][0][i][j].ssum * 100LL
+ 20LL * d * dp[p+1][0][i][j].sum + d*d * dp[p+1][0][i][j].num; 92 dp[p][0][ii][jj].ssum %= MOD; 93 } 94 } 95 } 96 } 97 98 ll calcu(ll N) 99 { 100 ll len = Len(N); 101 ini(len); 102 dp[len+1][0][0][0].num = 1; 103 DP(len); 104 ll ret = 0; 105 for(ll i=1; i<7; i++){ 106 for(ll j=1; j<7; j++){ 107 ret += dp[1][0][i][j].ssum; 108 ret += dp[1][1][i][j].ssum; 109 } 110 } 111 ret %= MOD; 112 return ret; 113 } 114 115 int main() 116 { 117 ll T; 118 cin >> T; 119 while(T--){ 120 ll A,B; 121 cin >> A >> B; 122 ll ans = 0; 123 ans = calcu(B) - calcu(A - 1); 124 ans = (ans + MOD) % MOD; 125 cout << ans << endl; 126 } 127 return 0; 128 }

 

 

 

 

posted on 2013-03-22 05:42  Lattexiaoyu  阅读(427)  评论(0编辑  收藏  举报

导航