• HDU 4507 吉哥系列故事——恨7不成妻 (数位DP)


    题意:

      如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关:
      1、整数中某一位是7;
      2、整数的每一位加起来的和是7的整数倍;
      3、这个整数是7的整数倍;

      给定一个区间[L,R],问在此区间内和7无关的所有数字的平方和。

    思路:

      第一步好解决,只是数位DP的基础。第二步是十进制的所有位加起来是7的整数倍,这个只是需要用多一维来记录%7的结果就行了。第三步是7的整数倍问题,假设c=a+b,那么c%7=(a%7+b)%7,就假设这个数是10086,那么(10000%7+86)%7就行了,一样可以通过增加一维来解决。最后还要解决平方和问题,如第三步,(a+b)2=a2+2ab+b2,而∑(b2)部分已经在前面完成了,我们需要将其记录起来。剩下a2+2ab需要解决,∑(a2)直接算,∑(2ab)=2a*∑(b),所以∑(b)也是需要记录的,而求和∑就需要知道前面到底有几个数是合法的才行,则需要记录个数cnt。所以一共需要用到3维的数组,其中需要记录合法个数cnt,数的和sum,数的平方和ssum。

     1 #include <bits/stdc++.h>
     2 #define pii pair<int,int>
     3 #define INF 0x7f3f3f3f
     4 #define LL long long
     5 #define ULL unsigned long long
     6 using namespace std;
     7 const double PI  = acos(-1.0);
     8 const int N=19;
     9 const LL mod=1e9+7;
    10 
    11 struct node
    12 {
    13 /*
    14     1.与7无关的数的个数
    15     2.与7无关的数的和
    16     3.与7无关的数的平方和。
    17 */
    18     ULL  cnt;
    19     ULL  sum;
    20     ULL  ssum;
    21 }dp[N][7][7];
    22 
    23 void pre_cal()
    24 {
    25     ULL base=dp[0][0][0].cnt=1;
    26     for(int i=1; i<N; i++,base*=10 ) //位数
    27     {
    28         for(int u=0; u<10; u++) //第i位为u
    29         {
    30             if(u==7)    continue;   //不合法
    31             ULL c=u*base%mod;
    32 
    33             for(int j=0; j<7; j++)  //位和
    34             for(int k=0; k<7; k++)  //数和
    35             {
    36                 ULL a=(u+j)%7, b=(u*base+k)%7;
    37                 ULL sum =dp[i-1][j][k].sum,ssum=dp[i-1][j][k].ssum,cnt =dp[i-1][j][k].cnt;;
    38 
    39                 dp[i][a][b].cnt +=cnt;                              //个数
    40                 dp[i][a][b].cnt %=mod;
    41                 dp[i][a][b].sum +=sum +c*cnt%mod;                   //
    42                 dp[i][a][b].sum %=mod;
    43                 dp[i][a][b].ssum+=ssum + 2*c*sum%mod + cnt*c%mod*c%mod;//平方和:3部分
    44                 dp[i][a][b].ssum%=mod;
    45             }
    46         }
    47     }
    48 }
    49 
    50 int bit[N+2];
    51 ULL cal(ULL n)
    52 {
    53     memset(bit, 0, sizeof(bit));
    54     ULL base=1, ans=0, len=0, i, pre=0, bsum=0; //bsum记录前缀的位和
    55     while(n)
    56     {
    57         bit[++len]=n%10;
    58         n/=10;
    59         base*=10;
    60     }
    61     for( i=len; i>0; i--)
    62     {
    63         base/=10;
    64         for(int u=0; u<bit[i]; u++)     //当前位
    65         {
    66             if(u==7) continue;
    67             ULL c=(pre*10+u)*base%mod;  //前缀,注意c已经取模了
    68             for(int a=0; a<7; a++)      //位和
    69                 for(int b=0; b<7; b++)  //数和
    70                     if( (bsum+u+a)%7 && ( (pre*10%7+u)*base+b)%7 )
    71                     {
    72                         ULL cnt=dp[i-1][a][b].cnt;
    73                         ULL sum=dp[i-1][a][b].sum;
    74                         ULL ssum=dp[i-1][a][b].ssum;
    75 
    76                         ans+= ssum + 2*c*sum%mod + cnt*c%mod*c%mod ;
    77                         ans%=mod;
    78                     }
    79         }
    80         pre=pre*10+bit[i];
    81         bsum+=bit[i];   //前缀的位和
    82         if(bit[i]==7)   break;  //前缀出现了7,后面不可能了
    83     }
    84     return ans%mod;
    85 }
    86 
    87 int main()
    88 {
    89     //freopen("input.txt","r",stdin);
    90     pre_cal();
    91     LL L, R;
    92     int t;cin>>t;
    93     while(t--)
    94     {
    95         scanf("%lld %lld",&L,&R);
    96         printf("%llu
    ", (cal(R+1)-cal(L)+mod)%mod );
    97     }
    98     return 0;
    99 }
    AC代码
  • 相关阅读:
    django模板使用
    django视图的定义
    字符串逆序
    Django 中Admin站点的配置
    Django模型Model的定义
    Django安装部署
    Linux常用命令
    深拷贝,浅拷贝
    lambda 表达式 (匿名函数)
    生成器与迭代器
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4853574.html
Copyright © 2020-2023  润新知