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