2 条题解

  • 0
    @ 2025-10-8 16:58:46

    很明显的一道记搜,三个条件用普通dp不好转移状态 定义一个结构体,分别表示数的个数,总和,平方和 用数学思想即可解决

    #include<bits/stdc++.h> //by: hansang.tamoto ring
    using namespace std;
    typedef long long LL;
    const int N=30;
    const LL P=1e9+7;
    struct node{
        LL cnt, sum, sum2;
        //个数,总和,平方和
    }f[N][10][10]; LL a[N], d[N]; 
    node dfs(int x, int sum, int num, bool lim){ 
        //sum是各个数位的和%7余数,num是数本身%7余数
        if(x==0) return (node){sum && num, 0, 0}; 
        //只有两个都不能整除才能算答案
        if(!lim && f[x][sum][num].cnt>0) return f[x][sum][num];
        int up=lim? a[x]: 9; node ans=(node){0, 0, 0};
        for(int i=0; i<=up; i++) if(i!=7){
            node no=dfs(x-1, (sum+i)%7, (num*10+i)%7, lim && (i==up));
            LL B=i*d[x-1]%P;
            ans.cnt=(ans.cnt+no.cnt)%P; //个数和直接加上
            ans.sum=(ans.sum+no.cnt*B%P+no.sum)%P;
            //相当于把i接到no里面的数前面,加上cnt*i*10的x-1次方
            ans.sum2=((ans.sum2+no.cnt*B%P*B%P)%P+
            (no.sum2+2*no.sum%P*B%P)%P)%P;
            /*重点
            假设no中的数为x1~xcnt,我们有x1^2+x2^2+...+xcnt^2
            要求(x1+B)^2+(x2+B)^2+...(xcnt+B)^2
            拆出来:(x1^2+2*x1*B+B^2)+(x2^2+2*x2*B+B^2)+... 
                   +(xcnt^2+2*xcnt*B+B^2)
            合并同类项:(x1^2+x2^2+...+xcnt^2)+2*B*(x1+x2+...+xcnt)
                      +cnt*B^2
                    = sum2+cnt*B^2+2*B*sum
            */
        }
        if(!lim) f[x][sum][num]=ans;
        return ans;
    }
    LL calc(LL x){
        int len=0;
        while(x>0) a[++len]=x%10, x/=10;
        return dfs(len, 0, 0, 1).sum2;
    }
    int main(){
        //freopen("a.in", "r", stdin);
        d[0]=1; for(int i=1; i<=25; i++) d[i]=d[i-1]*10%P; //预处理10的次方
        int T; scanf("%d", &T);
        while(T--){
            LL n, m; scanf("%lld%lld", &n, &m);
            printf("%lld\n", (calc(m)-calc(n-1)+P)%P);
        }
        return 0;
    }
    
    • 0
      @ 2025-10-8 16:58:37
      /*
      很明显的一道记搜,三个条件用普通dp不好转移状态
      定义一个结构体,分别表示数的个数,总和,平方和
      用数学思想即可解决
      */
      #include<bits/stdc++.h> //by: hansang.tamoto ring
      using namespace std;
      typedef long long LL;
      const int N=30;
      const LL P=1e9+7;
      struct node{
          LL cnt, sum, sum2;
          //个数,总和,平方和
      }f[N][10][10]; LL a[N], d[N]; 
      node dfs(int x, int sum, int num, bool lim){ 
          //sum是各个数位的和%7余数,num是数本身%7余数
          if(x==0) return (node){sum && num, 0, 0}; 
          //只有两个都不能整除才能算答案
          if(!lim && f[x][sum][num].cnt>0) return f[x][sum][num];
          int up=lim? a[x]: 9; node ans=(node){0, 0, 0};
          for(int i=0; i<=up; i++) if(i!=7){
              node no=dfs(x-1, (sum+i)%7, (num*10+i)%7, lim && (i==up));
              LL B=i*d[x-1]%P;
              ans.cnt=(ans.cnt+no.cnt)%P; //个数和直接加上
              ans.sum=(ans.sum+no.cnt*B%P+no.sum)%P;
              //相当于把i接到no里面的数前面,加上cnt*i*10的x-1次方
              ans.sum2=((ans.sum2+no.cnt*B%P*B%P)%P+
              (no.sum2+2*no.sum%P*B%P)%P)%P;
              /*重点
              假设no中的数为x1~xcnt,我们有x1^2+x2^2+...+xcnt^2
              要求(x1+B)^2+(x2+B)^2+...(xcnt+B)^2
              拆出来:(x1^2+2*x1*B+B^2)+(x2^2+2*x2*B+B^2)+... 
                     +(xcnt^2+2*xcnt*B+B^2)
              合并同类项:(x1^2+x2^2+...+xcnt^2)+2*B*(x1+x2+...+xcnt)
                        +cnt*B^2
                      = sum2+cnt*B^2+2*B*sum
              */
          }
          if(!lim) f[x][sum][num]=ans;
          return ans;
      }
      LL calc(LL x){
          int len=0;
          while(x>0) a[++len]=x%10, x/=10;
          return dfs(len, 0, 0, 1).sum2;
      }
      int main(){
          //freopen("a.in", "r", stdin);
          d[0]=1; for(int i=1; i<=25; i++) d[i]=d[i-1]*10%P; //预处理10的次方
          int T; scanf("%d", &T);
          while(T--){
              LL n, m; scanf("%lld%lld", &n, &m);
              printf("%lld\n", (calc(m)-calc(n-1)+P)%P);
          }
          return 0;
      }
      • 1

      *【数位DP】[HDU4507] 恨 7 不成妻

      信息

      ID
      1821
      时间
      1000ms
      内存
      512MiB
      难度
      7
      标签
      (无)
      递交数
      77
      已通过
      16
      上传者