zoukankan      html  css  js  c++  java
  • Day9

    单身!
      依然单身!
      吉哥依然单身!
      DS级码农吉哥依然单身!
      所以,他生平最恨情人节,不管是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无关的数字的平方和。

    Input输入数据的第一行是case数T(1 <= T <= 50),然后接下来的T行表示T个case;每个case在一行内包含两个正整数L, R(1 <= L <= R <= 10^18)。
    Output请计算[L,R]中和7无关的数字的平方和,并将结果对10^9 + 7 求模后输出。Sample Input

    3
    1 9
    10 11
    17 17

    Sample Output

    236
    221
    0

    思路:还是数位DP,套用模板,求的是平方和,记录其后数位满足条件的个数即可,比如233, 234, 235满足,则平方和为(200+33)^2+(200+34)^2+(200+35)^2 = 3*200^2 + 2*200*(33+34+35)+33^2+34^2+35^2,记录下每次的和与平方和维护即可
    typedef long long LL;
    typedef pair<LL, LL> PLL;
    
    const int MOD = 1e9+7;
    
    struct Node {
        LL num, sum, ssum;
    } dp[20][10][10];
    
    LL a[20], p[20];
    
    Node dfs(int pos, int pre, int presum, bool limit) {
        if(pos == -1) {
            Node ret;
            ret.num = (pre != 0 && presum != 0);
            ret.sum = ret.ssum = 0;
            return ret;
        }
        if(!limit && dp[pos][pre][presum].num != -1) return dp[pos][pre][presum];
        int up = limit?a[pos]:9;
        Node ans;
        ans.num = ans.sum = ans.ssum = 0;
        for(int i = 0; i <= up; ++i) {
            if(i == 7) continue;
            Node nex = dfs(pos-1, (pre+i)%7, (presum*10+i)%7, limit&&i==a[pos]);
            if(nex.num == 0) continue;
            ans.num = ((ans.num + nex.num) % MOD + MOD) % MOD;
            ans.sum = ((ans.sum + nex.sum + (p[pos]*i)%MOD*nex.num) % MOD + MOD) % MOD;
            ans.ssum = ((ans.ssum + nex.ssum + ((2*p[pos]*i) % MOD)*nex.sum) % MOD + MOD) % MOD;
            ans.ssum = ((ans.ssum + (p[pos]*nex.num)%MOD * p[pos] % MOD *i*i) % MOD + MOD) % MOD;
        }
        if(!limit) dp[pos][pre][presum] = ans;
        return ans;
    }
    
    LL solve(LL n, LL m) {
        int pos = 0;
        while(n) {
            a[pos++] = n % 10;
            n /= 10;
        }
        LL t1 = dfs(pos-1, 0, 0, true).ssum;
        pos = 0;
        while(m) {
            a[pos++] = m % 10;
            m /= 10;
        }
        t1 = dfs(pos-1, 0, 0, true).ssum - t1;
        return (t1%MOD+MOD)%MOD;
    }
    
    void run_case() {
        
        LL n, m;
        cin >> n >> m;
        cout << solve(n-1, m) << "
    ";
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        int t;
        cin >> t;
        for(int i = 0; i < 20; ++i)
            for(int j = 0; j < 10; ++j)
                for(int k = 0; k < 10; ++k)
                    dp[i][j][k].num = -1;
        p[0] = 1;
        for(int i = 1; i < 20; ++i)
            p[i] = (p[i-1]*10)%MOD;
        while(t--) 
            run_case();
        return 0;
    }
    View Code
    
    
  • 相关阅读:
    用DeBug的方式,带你掌握HBase文件在Snapshot的各种变化
    业务随行:用户的网络访问策略还能这么玩
    清明节特辑 |记忆存储、声音还原、性格模仿……AI可以让人类永生吗?
    答题拿奖两不误:华为云知乎金牌答题官,就是你!
    一文掌握GaussDB(DWS) SQL进阶技能:全文检索
    LiteOS内核源码分析:任务栈信息
    INTERSPEECH2020 语音情感分析论文之我见
    统一元数据,数据湖Catalog让大数据存算分离不再是问题
    云图说|将源端MongoDB业务搬迁至华为云DDS的几种方式
    跟我学丨如何用鲲鹏服务器搭建Hadoop全分布式集群
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12245287.html
Copyright © 2011-2022 走看看