zoukankan      html  css  js  c++  java
  • 卷积和

    题意:

    假定数字$x = d_0d_1d_2d_3...d_{n-1}$,则$F(x) = sum_{i=0}^n{d_i d_{n-i-1}}$

    求$sum_{i = L}^R {F(i)}$ 的值。

    解法:

    只要求出 $S(n) = sum_{i = 1}^{n-1} {F(i)}$

    1. 先统计数位小于 $n$ 的数位的(分三 / 两种情况)。

    2. 考虑枚举数位,假定当前还剩下$len$位没有确认,首先考虑如果长度为奇数,统计一下。

      对于接下来剩下的 $[frac{tot}{2}]$ 对,按照有一个确定,有两个确定,有三个确定分类。

    $O(log^2n)$

    想清楚再写,QAQ

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    
    #define LL long long
    #define P 1000000007LL
    #define N 110
    
    using namespace std;
    
    int num[N], v[N];
    LL cnt[10][10], power[N];
    
    void solve(int tot)
    {
        if(tot == 1)
        {
            for(int i = 1;i <= 9;i++)
                cnt[i][i]++;
        }
        else
        {
            for(int i = 1;i <= 9;i++)
                for(int j = 1;j <= 9;j++)
                    cnt[i][j] += 2LL * power[tot-2] % P;
            if(tot == 2) return;
            if(tot & 1)
            {
                for(int i = 1;i <= 9;i++)
                    cnt[i][i] += 9LL * power[tot-2] % P;
            }
            LL tmp = (tot-2)/2LL;
            for(int i = 1;i <= 9;i++)
                for(int j = 1;j <= 9;j++)
                    cnt[i][j] += (2LL * tmp * power[tot-3] * 9LL) % P;
        }
    }
    
    void solve(int tot, int len)
    {
        if(tot & 1)
        {
            int tmp = tot/2 + 1;
            if(v[tmp] == -1)
            {
                for(int i = 1;i <= 9;i++)
                    cnt[i][i] += power[len-1];
            }
            else cnt[v[tmp]][v[tmp]] += power[len];
        }
        for(int i = 1;i <= tot/2;i++)
        {
            if(v[i] >= 0)
                cnt[v[i]][v[tot-i+1]] += 2ll * power[len] % P;
            else
            {
                if(v[tot-i+1] >= 0)
                {
                    for(int j = 1;j <= 9;j++)
                        if(len > 0) cnt[j][v[tot-i+1]] += 2LL * power[len-1] % P;
                }
                else
                {
                    for(int j = 1;j <= 9;j++)
                        for(int k = 1;k <= 9;k++)
                            cnt[j][k] += 2LL * power[len-2] % P;
                }
            }
        }
    }
    
    LL calc(LL n)
    {
        memset(v, -1, sizeof(v));
        memset(cnt, 0, sizeof(cnt));
        int tot = 0;
        for(;n;n /= 10) num[++tot] = n%10;
        for(int i = 1;i < tot;i++) solve(i);
        for(int i = tot;i >= 1;i--)
        {
            for(int j = (i == tot? 1:0);j < num[i];j++)
                v[i] = j, solve(tot, i-1);
            v[i] = num[i];
        }
        LL ans = 0;
        for(int i = 1;i <= 9;i++)
            for(int j = 1;j <= 9;j++)
            {
                cnt[i][j] %= P;
                ans += (i * (LL)j * cnt[i][j]) %P;
            }
        return ans % P;
    }
    
    int main()
    {
        power[0] = 1;
        for(int i = 1;i < N;i++) power[i] = power[i-1] * 10LL % P;
        LL a, b;
        cin >> a >> b;
        cout << (calc(b+1) + P - calc(a)) % P << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    ARM(ARM处理器)
    Android系统
    2014-9-17二班----11 web project
    2014-9-17二班----10 web project
    append() 、push() 和pop()的区别
    python hash
    虚拟机卡掉
    虚拟化
    heroinfo_set.all 函数
    encode()和decode()两个函数
  • 原文地址:https://www.cnblogs.com/lawyer/p/6803826.html
Copyright © 2011-2022 走看看