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


    吉哥系列故事——恨7不成妻

    传送门

    Problem Description

      单身!
      依然单身!
      吉哥依然单身!
      DS级码农吉哥依然单身!
      所以,他生平最恨情人节,不管是214还是77,他都讨厌!
      
      吉哥观察了214和77这两个数,发现:
      2+1+4=7
      7+7=72
      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[i][j][k]表示第i位,各位数和%7=j,前面的数字%7=k的状态
    记录与7无关的数的个数(sum),与7无关的数和(qsum),以及平方和(sqsum)
    与7无关的数的平方和=(sum(i*10^{pos}+num)^2=i*i*10^{2*pos}*sum+2*i*10^{pos}*qsum+sqsum)

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    /*    freopen("k.in", "r", stdin);
        freopen("k.out", "w", stdout); */
    //clock_t c1 = clock();
    //std::cerr << "Time:" << clock() - c1 <<"ms" << std::endl;
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #define de(a) cout << #a << " = " << a << endl
    #define rep(i, a, n) for (int i = a; i <= n; i++)
    #define per(i, a, n) for (int i = n; i >= a; i--)
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    typedef vector<int, int> VII;
    #define inf 0x3f3f3f3f
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MAXN = 1e6 + 7;
    const ll MAXM = 1e6 + 7;
    const ll MOD = 1e9 + 7;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    int a[105];
    /*   1、整数中某一位是7;
      2、整数的每一位加起来的和是7的整数倍;
      3、这个整数是7的整数倍; */
    struct node
    {
        ll sum;   //与7无关的数的个数
        ll qsum;  //与7无关的数和
        ll sqsum; //ans
        node(ll _sum = -1, ll _qsum = 0, ll _sqsum = 0) { sum = _sum, qsum = _qsum, sqsum = _sqsum; }
    };
    node dp[30][15][15];
    ll c[20];
    node dfs(int pos, int sta1, int sta2, bool lim) //sta1各位数和%7 sta2前面%7
    {
        if (pos < 0)
            return node(sta1 && sta2, 0, 0);
        if (!lim && dp[pos][sta1][sta2].sum != -1)
            return dp[pos][sta1][sta2];
        int up = lim ? a[pos] : 9;
        node ret = node(0, 0, 0);
        for (int i = 0; i <= up; i++)
        {
            if (i != 7)
            {
                node t = dfs(pos - 1, (sta1 + i) % 7, (sta2 * 10 + i) % 7, lim && i == a[pos]);
                ret.sum += t.sum;
                ret.sum %= MOD;
                ret.qsum += (((c[pos] * i % MOD) * t.sum % MOD) + t.qsum) % MOD;
                ret.qsum %= MOD;
                ret.sqsum += t.sqsum % MOD;
                ret.sqsum %= MOD;
                ret.sqsum += ((i * i * c[pos] % MOD) * c[pos] % MOD) * t.sum % MOD;
                ret.sqsum %= MOD;
                ret.sqsum += ((i * 2 * c[pos] % MOD) * t.qsum) % MOD;
                ret.sqsum %= MOD;
            }
        }
        if (!lim)
            dp[pos][sta1][sta2] = ret;
        return ret;
    }
    ll solve(ll x)
    {
        int pos = -1;
        while (x)
        {
            a[++pos] = x % 10;
            x /= 10;
        }
        return dfs(pos, 0, 0, true).sqsum;
    }
    void init()
    {
        c[0] = 1;
        for (int i = 1; i < 20; i++)
            c[i] = (c[i - 1] * 10) % MOD;
    }
    
    int main()
    {
        int t;
        init();
        scanf("%d", &t);
        while (t--)
        {
            ll L, R;
            scanf("%lld%lld", &L, &R);
            printf("%lld
    ", ((solve(R) - solve(L - 1)) % MOD + MOD) % MOD);
        }
        return 0;
    }
    
  • 相关阅读:
    HBase 负载均衡
    HBase的写事务,MVCC及新的写线程模型
    HBase RegionServer宕机处理恢复
    分布式事务实现-Percolator
    MVC框架
    06-JS中li移动第二种形式
    05-JS中li移动第一种形式
    04-JS中文档碎片
    03-JS中添加节点
    02-JS中父节点
  • 原文地址:https://www.cnblogs.com/graytido/p/12202754.html
Copyright © 2020-2023  润新知