测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

A22621. 数字之和

填空题 困难

题目描述

数字之和

题目描述

给定一个数字字符串 n,定义一次操作为:移除字符串中一个非空子串,并将剩余部分拼接形成新数字。

求所有可能操作方案生成的新数字之和,结果对 109+7 取模。

输入格式

一行字符串 n

输出格式

一个整数,表示所有方案生成数字之和取模后的结果。

输入样例#1

1003

输出样例#1

339

输入样例#2

123

输出样例#2

52

说明提示

1≤∣n∣≤105,| n |表示字符串长度。

参考答案

#include <bits/stdc++.h> using namespace std; const int MOD = 1e9 + 7; const int MAX_LEN = 1e5 + 10; long long pow10[MAX_LEN]; long long inv9, inv81; long long mod_pow(long long base, long long exp, int mod) { long long result = 1; while (exp > 0) { if (exp % 2 == 1) { result = (result * base) % mod; } base = (base * base) % mod; exp /= 2; } return result; } void precompute(int L) { pow10[0] = 1; for (int i = 1; i <= L; ++i) { pow10[i] = (pow10[i - 1] * 10) % MOD; } inv9 = mod_pow(9, MOD - 2, MOD); inv81 = mod_pow(81, MOD - 2, MOD); } int main() { string n; cin >> n; int L = n.size(); precompute(L); long long ans = 0; for (int k = 0; k < L; ++k) { int d = n[k] - '0'; if (d == 0) { continue; // 贡献为0,可直接跳过 } // 计算左侧贡献 long long left = 0; if (k > 0) { long long count = (1LL * k * (k + 1)) / 2 % MOD; int exponent = L - k - 1; long long pow_val = pow10[exponent]; left = (count * pow_val) % MOD; } // 计算右侧贡献 long long right = 0; int exponent = L - k - 1; if (exponent > 0) { long long part1 = (1LL * (L - k - 1) * pow10[exponent]) % MOD; long long term1 = (part1 * inv9) % MOD; long long part2 = (pow10[exponent] - 1 + MOD) % MOD; long long term2 = (part2 * inv81) % MOD; right = (term1 - term2 + MOD) % MOD; } long long total = (left + right) % MOD; ans = (ans + 1LL * d * total) % MOD; } cout << ans << endl; return 0; }
上一题 下一题