Codeforces Round #675 (Div. 2)
去掉一段连续的区间后累加
枚举每一位的贡献,假设该位没有被删除。
从左到右第 i i i位,长度为 n n n
1 2 ∗ ( i − 1 ) ∗ i ∗ s t r [ i ] ∗ 1 0 n − i \frac{1}{2}*(i-1)*i*str[i]*10^{n-i} 21∗(i−1)∗i∗str[i]∗10n−i
在前面任取一段连续的区间可能数为 C i 2 C_i^2 Ci2,乘以 s t r [ i ] str[i] str[i]的贡献
删除区间长度为 x x x s t r [ i ] ∗ ∑ 1 n − i ( n − i − x + 1 ) ∗ 1 0 n − i − x str[i]*\sum_1^{n-i} (n-i-x+1)*10^{n-i-x} str[i]∗1∑n−i(n−i−x+1)∗10n−i−x 通过代换可以转换为 s t r [ i ] ∗ ∑ 0 n − i − 1 ( t + 1 ) ∗ 1 0 t str[i]*\sum_0^{n-i-1} (t+1)*10^t str[i]∗0∑n−i−1(t+1)∗10t
#include<bits/stdc++.h> using namespace std; #define int long long const int mod=1e9+7; char str[100010]; int f[100010],p10[100010]; int res(int x){ return x*(x-1)/2%mod; } void solve(){ scanf("%s",str+1); int n=strlen(str+1); p10[0]=1; for(int i=1;i<=100005;++i){ p10[i]=p10[i-1]*10; p10[i]%=mod; } f[0]=1; for(int i=1;i<=100005;++i){ f[i]=f[i-1]+(i+1)*p10[i]; f[i]%=mod; } int ans=0; for(int i=1;i<=n;++i){ int pre=res(i)*(str[i]-'0')%mod*p10[n-i]; int be=(str[i]-'0')*f[n-i-1]; ans+=pre+be; ans%=mod; } printf("%lld\n",ans); } signed main(){ int t=1; // scanf("%lld",&t); while(t--){ solve(); } }