Codeforces Round #675 (Div. 2)C. Bargain(組合數學+貢獻)

題意

去掉一段連續的區間後累加c++

思路

枚舉每一位的貢獻,假設該位沒有被刪除。spa

從左到右第\(i\)位,長度爲\(n\)code

假設刪除該位前面連續的區間

\[\frac{1}{2}*(i-1)*i*str[i]*10^{n-i} \]

在前面任取一段連續的區間可能數爲\(C_i^2\),乘以\(str[i]\)的貢獻it

假設刪除該位後面連續的區間

刪除區間長度爲\(x\)class

\[str[i]*\sum_1^{n-i} (n-i-x+1)*10^{n-i-x} \]

經過代換能夠轉換爲di

\[str[i]*\sum_0^{n-i-1} (t+1)*10^t \]

#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();
    }

}
相關文章
相關標籤/搜索