传送门

本来是非常简单的一题…

一步想错步步想错…

很明显需要枚举每个数字来计算贡献

比如考虑第 i i i位数字的贡献

第 一 部 分 \color{Red}第一部分

若删除 [ i + 1 , n ] [i+1,n] [i+1,n]间的子串,删去长度为 j j j的,还剩下 n − i − j n-i-j nij

贡献是 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=1ni(nij+1)10nij

发现 n − i − j + 1 n-i-j+1 nij+1的范围在区间 [ 1 , n − i ] [1,n-i] [1,ni]浮动

所以贡献就是 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=1nij10j1

当考虑 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=1ni1j10j1

发现也就是少了一个 ( n − i ) ∗ 1 0 n − i − 1 (n-i)*10^{n-i-1} (ni)10ni1

从前往后或从后往前都可以快速计算

第 二 部 分 \color{Red}第二部分

若删除 i i i之前的子串,贡献是 a [ i ] ∗ i ∗ ( i − 1 ) / 2 a[i]*i*(i-1)/2 a[i]i(i1)/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;
}