当前位置: 代码迷 >> 综合 >> Codeforces Round #675 (Div. 2)C. Bargain(组合数学+贡献)
  详细解决方案

Codeforces Round #675 (Div. 2)C. Bargain(组合数学+贡献)

热度:14   发布时间:2024-02-25 11:08:29.0

题意

去掉一段连续的区间后累加

思路

枚举每一位的贡献,假设该位没有被删除。

从左到右第iii位,长度为nnn

假设删除该位前面连续的区间

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

在前面任取一段连续的区间可能数为Ci2C_i^2Ci2?,乘以str[i]str[i]str[i]的贡献

假设删除该位后面连续的区间

删除区间长度为xxx
str[i]?∑1n?i(n?i?x+1)?10n?i?xstr[i]*\sum_1^{n-i} (n-i-x+1)*10^{n-i-x} str[i]?1n?i?(n?i?x+1)?10n?i?x
通过代换可以转换为
str[i]?∑0n?i?1(t+1)?10tstr[i]*\sum_0^{n-i-1} (t+1)*10^t str[i]?0n?i?1?(t+1)?10t

#include<bits/stdc++.h>using namespace std;
#define int long longconst 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();}}
  相关解决方案