CodeForces 520E Pluses everywhere

来源:互联网 发布:淘宝售假进货凭证截图 编辑:程序博客网 时间:2024/06/05 04:38

传送门:http://codeforces.com/problemset/problem/520/E


有一串n个数,在n个数中插入k个加号,拆成k+1个数,求着n*(k+1)的数的和是多少


当然,暴力枚举是不可以的hhh,所以要考虑别的思路

对于一个数12345相当于1*10^4+2*10^3+3*10^1+4*10^0

所以只要考虑每一个数在每一位上的次数

从低到高分别为1~n位

则每一位可以充当的是第1~i-1位,再通过组合数计算总数,当然不合法的情况用组合数为0干掉就好

然后公式的话


就酱

然后,会遇到两个问题,一个是组合数取模

具体方法以后再放链接

二是优化的问题,要预处理sigma(10^(j-1)*C(n-j-1,k-1))否则就是O(n^2)的算法,预处理的话是O(n)的


代码如下:

#include<cstdio>#include<cstring>#define MOD 1000000007using namespace std;int n,k;long long ans=0;int s[100005];long long t[100005];long long fact[100005];long long f[100005];long long inv[100005];long long d[100005];char op;void getfact(){fact[0]=fact[1]=inv[0]=inv[1]=f[0]=f[1]=1; for (int i=2;i<=n;i++){fact[i]=fact[i-1]*i%MOD;f[i]=(MOD-MOD/i)*f[MOD%i]%MOD;inv[i]=inv[i-1]*f[i]%MOD;}}long long C(int n,int m){if (m>n || m<0){return 0;}return fact[n]*inv[m]%MOD*inv[n-m]%MOD;}int main(){scanf("%d%d",&n,&k);getchar();t[0]=1;for (int i=1;i<=n;i++){t[i]=(t[i-1]*10)%MOD;}if (k){for (int i=n;i;i--){op=getchar();s[i]=op-'0';}d[0]=0;getfact();for (int i=1;i<=n;i++){d[i]=d[i-1]+t[i-1]*C(n-i-1,k-1);d[i]%=MOD; }ans=0;for (int i=1;i<=n;i++){ans+=s[i]*((t[i-1]*C(n-i,k)%MOD+d[i-1])%MOD);ans%=MOD;}}else{for (int i=1;i<=n;i++){op=getchar();s[i]=op-'0';}ans=0;for (int i=1;i<=n;i++){ans+=s[i]*t[n-i];ans%=MOD;}}printf("%I64d\n",ans);return 0;}


0 0
原创粉丝点击