题意:
对于给定的字符串随机删除一些子串,对剩下的串构成的数字进行求和
思路:
对字符串遍历,每一个字符推公式求一次贡献值
设当前字符位置为i,数字为num,此时后面有len - i个数字,所以该字符删去后面的子串对答案的贡献为:
用高中数学错位相减化简后:
(num * (len - i) * pow(10, len - i) + num * (1 - pow(10, len - i)) / 9) / 9
删去前面的字串对答案的贡献值为:
化简后:
hh *(hh + 1) / 2 * num *pow(10, len - i)
实现:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <map>
#include <set>
#include <climits>
#include <unordered_map>
using namespace std;
#define mst(x, y) memset(x, y, sizeof x)
#define X first
#define Y second
#define int long long
#define FAST ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
const int N = 200010, INF = 0x3f3f3f3f3f3f3f3f, MOD = 1e9 + 7;
const double EPS = 1e-6;
typedef pair<int, int> PII;
typedef unordered_map<int, int> Ump;
int T;
string s;
int qmi(int a, int k) // 求a^k mod p
{
int res = 1;
while (k)
{
if (k & 1)
res = res * a % MOD;
a = a * a % MOD;
k >>= 1;
}
return res;
}
void solve()
{
cin >> s;
s = " " + s;
int tt = qmi(9, MOD - 2);
int len = s.size() - 1;
int res = 0;
for (int i = len; i; i--)
{
int num = s[i] - '0';
int hh = i - 1;
res = (res + (hh * (hh + 1)) / 2 * num % MOD * qmi(10, len - i) % MOD) % MOD;
res = (res + (num * (len - i) * qmi(10, len - i) % MOD + num * (1 - qmi(10, len - i) + MOD) % MOD * tt % MOD) * tt % MOD) % MOD;
// cout << res << endl;
}
cout << res << endl;
}
signed main()
{
FAST;
// cin >> T;
T = 1;
while (T--)
solve();
return 0;
}