CF520E Pluses everywhere

枫林晚

2018-04-18 22:46:43

Personal

题目大意 给定一个 n 位的十进制数,可以在数字之间加 k 个' + ',得到一个式子,求每种方案的这个式子的和 分析: 容易想到将式子的和转化为每个数字的贡献值之和。 设数组a为:a(n-1),a(n-2),...,a(0); 对于每一个位置,我们可以以其右面第一个放加号的位置为界,确定它的数位和贡献值。 对于a(k),循环0~k-1;再加上k的贡献值。 发现贡献值可以预处理。 f[y]表示i=0~y循环,10^i x C(n-i-2,m-1)的值。 附代码: ```cpp #include<bits/stdc++.h> #define ll long long #define int long long using namespace std; const int N=1e5+10; const int mod=1e9+7; ll a[N],b[N]; int n,m; char c; ll fac[N],ifac[N]; ll f[N]; ll qm(int x,int y) { ll base=x%mod; ll ans=1; while(y) { if(y&1) ans=(ans*base)%mod; base=(base*base)%mod; y>>=1; } return ans%mod; } ll zu(int x,int y) { if(x<0||x<y||y<0) return 0; ll ret=fac[x]*ifac[y]%mod*ifac[x-y]%mod; return ret%mod; } ll ans=0; signed main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) { cin>>c; a[n-i]=c-'0'; } fac[0]=1; ifac[0]=1; for(int i=1;i<=n;i++) fac[i]=(fac[i-1]*i)%mod; ifac[n]=qm(fac[n],mod-2)%mod; for(int i=n-1;i>=1;i--) ifac[i]=(ifac[i+1]*(i+1))%mod; f[0]=zu(n-2,m-1); for(int i=1;i<=n;i++) f[i]=(f[i-1]+qm(10,i)*zu(n-i-2,m-1)%mod)%mod; for(int i=0;i<=n-1;i++) if(i) ans=(ans+a[i]*f[i-1]%mod+a[i]*qm(10,i)%mod*zu(n-i-1,m)%mod)%mod; else ans=(ans+a[i]*zu(n-1,m)%mod)%mod; printf("%lld",ans%mod); return 0; } ```