本来是非常简单的一题…
一步想错步步想错…
很明显需要枚举每个数字来计算贡献
比如考虑第 i i i位数字的贡献
第 一 部 分 \color{Red}第一部分 第一部分
若删除 [ i + 1 , n ] [i+1,n] [i+1,n]间的子串,删去长度为 j j j的,还剩下 n − i − j n-i-j n−i−j
贡献是 a [ i ] ∗ ∑ j = 1 n − i ( n − i − j + 1 ) ∗ 1 0 n − i − j a[i]*\sum\limits_{j=1}^{n-i}(n-i-j+1)*10^{n-i-j} a[i]∗j=1∑n−i(n−i−j+1)∗10n−i−j
发现 n − i − j + 1 n-i-j+1 n−i−j+1的范围在区间 [ 1 , n − i ] [1,n-i] [1,n−i]浮动
所以贡献就是 a [ i ] ∗ ∑ j = 1 n − i j ∗ 1 0 j − 1 a[i]*\sum\limits_{j=1}^{n-i}j*10^{j-1} a[i]∗j=1∑n−ij∗10j−1
当考虑 i + 1 i+1 i+1位数字的贡献时 a [ i + 1 ] ∗ ∑ j = 1 n − i − 1 j ∗ 1 0 j − 1 a[i+1]*\sum\limits_{j=1}^{n-i-1}j*10^{j-1} a[i+1]∗j=1∑n−i−1j∗10j−1
发现也就是少了一个 ( n − i ) ∗ 1 0 n − i − 1 (n-i)*10^{n-i-1} (n−i)∗10n−i−1
从前往后或从后往前都可以快速计算
第 二 部 分 \color{Red}第二部分 第二部分
若删除 i i i之前的子串,贡献是 a [ i ] ∗ i ∗ ( i − 1 ) / 2 a[i]*i*(i-1)/2 a[i]∗i∗(i−1)/2
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5+10;
const int mod = 1e9+7;
char a[maxn];
int one,ans;
int quick(int x,int n)
{
int ans = 1;
for(;n;n>>=1,x=x*x%mod)
if( n&1 ) ans = ans*x%mod;
return ans;
}
signed main()
{
cin >> (a+1);
int n = strlen( a+1 );
for(int i=n-1;i>=1;i--)
{
one = ( one+(n-i)*quick(10,n-i-1)%mod )%mod;
ans = ( ans+one*(a[i]-'0')%mod )%mod;
ans = ( ans+i*(i-1)/2%mod*(a[i]-'0')%mod*quick(10,n-i)%mod )%mod;
}
ans = ( ans+n*(n-1)/2%mod*(a[n]-'0')%mod )%mod;
cout << ans;
}