1 1 1 2 2 0 0 3 7 23 47 16
234 2799 72937Hint
解释在代码里:
#include<cstdio> #define MOD 10000007 using namespace std; typedef long long LL; #define rep(i,a,b) for(int i=a;i<b;i++) LL inv[11]; ///逆元 LL inv_fac[11]; ///阶乘逆元 LL n,m,a[11],tmp; /** 经过模拟之后发现ans=c(m,0)*a[n-1]+c(m+1,1)*a[n-2]+...c(m+n,n)*a[0]+c(n,0)*(23333...)+ c(n+1,1)*(2333...)+c(n+m-2,m-1)*233; 变形如下: ans=c(m,0)*a[n-1]+c(m+1,1)*a[n-2]+...c(m+n,n)*a[0]+c(n,n)*(23333...)+ c(n+1,n)*(2333...)+c(n+m-2,n)*233; ans=c(m,0)*a[n-1]+c(m+1,1)*a[n-2]+...c(m+n,n)*a[0]+{c(n,n)+ c(n+1,n)+c(n+m-2,n)}*233+2100*{10^(m-2)*c(n,n)+10^(m-3)*c(n+1,n)+10^0*c(n+m-4,n)}; ans=c(m,0)*a[n-1]+c(m+1,1)*a[n-2]+...c(m+n,n)*a[0]+c(n+m-1,n)*233 +2100*{10^(m-2)*c(n,n)+10^(m-3)*c(n+1,n)+10^0*c(n+m-4,n)}; 设f(n)={10^(m-2)*c(n,n)+10^(m-3)*c(n+1,n)+10^0*c(n+m-4,n)},则有f(n)=((10*f(n-1)-c(n+m-2,n))/9)%MOD; 即f(n)=(10*f(n-1)-c(n+m-2,n)*inv[9]%MOD; **/ void Init()///初始化数组 { int i; inv[0]=inv[1]=1; inv_fac[0]=inv_fac[1]=1; for(i=2;i<15;i++){ inv[i]=(inv[MOD%i]*(MOD-MOD/i))%MOD;///递推求逆元 inv_fac[i]=(inv_fac[i-1]*inv[i])%MOD;///递推求阶乘的逆元 } } LL C(LL N,LL k)///计算组合数 { if(k==0)return 1; LL i,ans=inv_fac[k]; for(i=0;i<k;i++) ans=ans*(N-i)%MOD; return ans; } LL quick_mod(LL x,LL N)///快速幂取模 { LL temp=x%MOD,result=1; while(N) { if(N&1) result=result*temp%MOD; temp=temp*temp%MOD; N>>=1; } return result; } LL f(LL N) { if(N==0) return (tmp-1+MOD)*inv[9]%MOD;///用到了等比数列求和sum[n]=a1(1-q^n)/(1-q); return (10*f(N-1)-C(N+m-2,N))*inv[9]%MOD; } void solve() { if(n==0&&m==0) { puts("0"); return; } tmp=quick_mod(10,m-1); LL ans=(C(n+m-1,n)*233+f(n)*2100)%MOD;///第一行的和乘组合数 int i; for(i=1;i<=n;i++) ans=(ans+C(n+m-1-i,n-i)*a[i-1])%MOD;///加上第一列的和乘组合数 printf("%I64d\n",ans); } int main() { Init(); while(~scanf("%I64d%I64d",&n,&m)) { rep(i,0,n){ scanf("%I64d",&a[i]); a[i]%=MOD; } solve(); } return 0; }
原文地址:http://blog.csdn.net/acvcla/article/details/39274391