卷积和
题意:
假定数字$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; }