1422 C. Bargain(推式子数学)
发布日期:2021-06-30 10:24:58 浏览次数:2 分类:技术文章

本文共 1341 字,大约阅读时间需要 4 分钟。

本来是非常简单的一题…

一步想错步步想错…

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

比如考虑第 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 
using namespace std;#define int long longconst 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;}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/110243810 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:牛客巅峰赛S2第四场.B.交叉乘(数学推导)
下一篇:1454F. Array Partition(思维....二分)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月24日 17时33分34秒