蒟蒻65分求助
查看原帖
蒟蒻65分求助
627886
duoaidaoc楼主2022/8/29 18:45
#include<bits/stdc++.h>
using namespace std;

long long f[20][10];
const int N = 1e9 + 7;

void init() {
    for (int j = 0;j <= 9;j++) {
        f[1][j] = j;
    }
    for (int i = 2;i <= 19;i++) {
        for (int j = 0;j <= 9;j++) {
            for (int cnt = 0;cnt <= 9;cnt++) {
                f[i][j] += f[i - 1][cnt];
            }
            f[i][j] += j * pow(10, i - 1);
            f[i][j] %= N;
        }
    }
    return;
}

long long fs(long long a) {
    int k[30], top = 0;
    memset(k, 0, sizeof(k));

    while (a > 0) {
        k[++top] = a % 10;
        a /= 10;
    }

    long long sum = 0;
    int hel = 0;
    for (int i = top; i >= 1;i--) {
        for (int j = 0;j < k[i];j++) {
            sum += f[i][j];
            sum %= N;
        }
        hel += k[i + 1];//属于(6+5+4+3)那一部分
        sum += hel * k[i] * pow(10, i - 1);
        sum %= N;
    }
    for (int i = 1;i <= top;i++) {
        sum += k[i];
    }

    return sum%N;
}
int main() {
    int t;
    scanf("%d", &t);
    init();
    for (int i = 1;i <= t;i++) {
        long long l, r;
        scanf("%lld%lld", &l, &r);
        printf("%lld\n", (fs(r)-fs(l-1))%N);
    }
    return 0;
}

我这里的f[i][j]表示以j为最高位的所有i位数的数字和的总和

例如f[3][2]表示200~299的数字和之和。

列出状态转移方程为 f[i][j] = f[i-1][0]+...+f[i-1][9]+j * 10^(i-1) 表示从000…00~999…99(i-1位)共10^(i-1)个数同时加了j

求0~某数的数字和也从最高位开始加起

例如求654321~0

f[6][0~5]表示从000000到599999

f[5][0~4]表示从00000到49999,加上 50000 * 6, 表示从600000到649999。

f[4][0~3]表示从0000到3999,加上 (6+5)* 4000表示从650000 到653999。

f[3][0~2]表示从000到299,加上 (6+5+4)* 300表示从654000 到654299。

f[2][0~1]表示从00到19,加上(6+5+4+3) * 20表示从654300到654319。

f[1][0]表示0,加上(6+5+4+3+2) * 1 表示654320。

最后剩下654321,sum加上6+5+4+3+2+1即可。

为什么会出错啊,65分....

求大佬解答。Orz

2022/8/29 18:45
加载中...