• 吉哥系列故事――恨7不成妻


    题目链接:https://vjudge.net/contest/365059#problem/J

    题目大意:求指定范围内与7不沾边的所有数的平方和。结果要mod 10^9+7

    想法:

    解题思路

    与7不沾边的数需要满足三个条件。

    ①不出现7

    ②各位数和不是7的倍数

    ③这个数不是7的倍数

    这三个条件都是基础的数位DP。

    但是这题要统计的不是符合条件个数,而是平方和。

    也就是说在DP时候,要重建每个数,算出平方,然后求和。

    需要维护三个值(推荐使用结构体), 假定dfs推出返回的结构体是next,当前结果的结构体是ans

    ①符合条件数的个数 cnt

    ②符合条件数的和 sum

    ③符合添加数的平方和 sqsum

    其中①是基础数位DP。②next.sum+(10^len*i)*ans.cnt,其中(10^len*i)*ans.cnt代表以len为首位的这部分数字和。

    ③首先重建一下这个数,(10^len*i+x),其中x是这个数的后面部分,则平方和就是(10^len*i)^2+x^2+2*10^len*i*x,其中x^2=next.sqsum

    整体还要乘以next.cnt,毕竟不止一个。

    sqsum+=next.sqsum

    sqsum+=(2*10^len*i*x)*next.cnt=(2*10^len*i)*next.sum

    sqsum+=(10^len*i)^2*next.cnt

    #pragma GCC optimize(3,"Ofast","inline")//O3优化
    #pragma GCC optimize(2)//O2优化
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    #include <bitset>
    #include <cmath>
    #include <sstream>
    #include <iostream>
    #include <cstring>
    
    #define LL long long
    #define ls nod<<1
    #define rs (nod<<1)+1
    #define pii pair<int,int>
    #define mp make_pair
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define max(a,b) (a>b?a:b)
    #define min(a,b) (a<b?a:b)
    
    const double eps = 1e-10;
    const int maxn = 2e5 + 10;
    const int mod = 1e9 + 7;
    
    int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
    using namespace std;
    
    LL L,R;
    int b[25];
    int len;
    LL p[25];
    
    struct node {
        LL cnt,sum,sqsum;
        node() {cnt = -1,sum = 0,sqsum = 0;}
        node(LL cnt,LL sum,LL sqsum):cnt(cnt),sum(sum),sqsum(sqsum){}
    }mem[20][10][10];
    
    node dfs(int cur,int r1,int r2,bool f) {
        if (cur < 0)
            return r1 !=0 && r2 != 0 ? node(1,0,0) : node(0,0,0);
        if (!f && mem[cur][r1][r2].cnt != -1)
            return mem[cur][r1][r2];
        int v = 9;
        if (f)
            v = b[cur];
        node ans;
        ans.cnt = 0;
        for (int i = 0;i <= v;i++) {
            if (i == 7)
                continue;
            node next = dfs(cur-1,(r1+i)%7,(r2*10+i)%7,f&&(i==v));
            ans.cnt += next.cnt;
            ans.cnt %= mod;
            ans.sum += (next.sum + (p[cur]*i)%mod*next.cnt%mod)%mod;
            ans.sum %= mod;
            ans.sqsum += (next.sqsum + (2*p[cur]*i)%mod*next.sum)%mod;
            ans.sqsum %= mod;
            ans.sqsum += (next.cnt*p[cur])%mod*p[cur]%mod*i*i%mod;
            ans.sqsum %= mod;
        }
        if (!f)
            mem[cur][r1][r2] = ans;
        return ans;
    }
    
    LL solve(LL x) {
        len = 0;
        while (x) {
            b[len++] = x % 10;
            x /= 10;
        }
        node ans = dfs(len-1,0,0,1);
        return ans.sqsum;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        int T;
        cin >> T;
        p[0] = 1;
        for (int i = 1;i <= 20;i++)
            p[i] = (p[i-1] * 10) % mod;
        while (T--) {
            cin >> L >> R;
            cout << (solve(R) - solve(L-1) + mod) % mod << endl;
        }
        return 0;
    }

     参考博客:https://www.cnblogs.com/neopenx/p/4008921.html

  • 相关阅读:
    springboot整合极光推送实现APP通知
    微信服务商AppID账号与商户号配置和查看
    linux-contos7中安装nginx
    centos 7 安装sql server 2017
    Redis集群高可用
    检查预约业务系统交互时序图
    特殊字符检测
    for循环执行原理
    Web.py报错:OSError: No socket could be created -- (('0.0.0.0', 8080):
    Oracle导出数据中的prompt,set feedback 等是什么意思
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12615446.html
Copyright © 2020-2023  润新知