题解:CF1422C Bargain
AC_OIKonjac · · 题解
Description
计算一个数字字符串中,所有可能的子串对应的数值之和,并对
Solution
对于字符串每一位数字
定义
当
- 左侧保留的起始位置有
i-1 种选择(1 ~i-1 ),删除的子串需在「左侧保留部分」和d 之间(或左侧保留部分之前),最终左侧保留方式共\frac{i \times (i-1)}{2} 种。 - 右侧保留的数字个数为
0 ~n-i ,对应的权重和为10^0 + 10^1 + ... + 10^{n-i} = 10^{n-i+1} - 1 。
贡献为
当
右侧保留的数字个数为
贡献为
第
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 1, P = 1e9 + 7;
ll n, ans;
ll pre_s[N], Pow[N];
string s;
int main() {
cin.tie(0)->sync_with_stdio(false);
cin >> s; n = s.size();
s = " " + s;
Pow[0] = 1;
for (int i = 1; i <= n; i++) {
Pow[i] = Pow[i - 1] * 10 % P;
pre_s[i] = (pre_s[i - 1] + i * Pow[i - 1]) % P;
}
for (int i = 1; i <= n; i++) {
if (i >= 2) {
ll c1 = 1LL * i * (i - 1) / 2 % P;
c1 = c1 * Pow[n - i] % P;
c1 = c1 * (s[i] - '0') % P;
ans = (ans + c1) % P;
}
ll c2 = 1LL * (s[i] - '0') * pre_s[n - i] % P;
ans = (ans + c2) % P;
}
cout << ans;
return 0;
}
Complexity Analysis
时空复杂度: