很末尾到首开始看每一位对总和的贡献=
倒数第一位:贡献了C(n-1,k)次个位数
倒数第二位:贡献了C(n-2,k-1)次个位数,C(n-2,k)次十位数
倒数第三位:贡献了C(n-2,k-1)次个位数,C(n-3,k-1)次十位数,C(n-3,k)次
倒数第四位:贡献了C(n-2,k-1)次个位数,C(n-3,k-1)次十位数,C(n-4,k-1)次百位数,C(n-4,k)次千位数
==
其实每位数贡献很明显,不难想到预处理出C(x,k-1)和C(x,k)然后利用前缀和思想统计即可=
哈哈,偷来了一个比大白书好看的exgcd求逆元模板==
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 #define MOD 1000000007 6 #define LL long long 7 #define ll I64 8 LL s[100005],c1[100005],c2[100005]; 9 LL inv(LL a) 10 { 11 LL b=MOD,b0=b,t,q,x0=0,x1=1; 12 if (b==1) return 1; 13 while (a>1) 14 { 15 q=a/b; 16 t=b,b=a%b,a=t; 17 t=x0,x0=x1-q*x0,x1=t; 18 } 19 if (x1<0) x1+=b0; 20 return x1; 21 } 22 int main() 23 { 24 LL n,k,i,ans,tmp,shi,j; 25 scanf("%lld%lld",&n,&k); 26 for (i=1;i<=n;i++) scanf("%1lld",&s[i]); 27 if (k==0){ 28 ans=0; 29 for (i=1;i<=n;i++) ans=(ans*10+s[i])%MOD; 30 printf("%lld\n",ans); return 0; 31 } 32 c1[k-1]=c2[k]=1; 33 for (i=k;i<=n;i++) 34 c1[i]=(c1[i-1]*i)%MOD*inv(i-k+1)%MOD; 35 for (i=k+1;i<=n;i++) 36 c2[i]=(c2[i-1]*i)%MOD*inv(i-k)%MOD; 37 ans=tmp=0; shi=j=1; 38 for (i=n;i>=1;i--) 39 { 40 if (i==n) ans=(ans+s[i]*c2[n-1])%MOD; 41 else { 42 j++; 43 tmp=(tmp+c1[n-j]*shi)%MOD; 44 shi=shi*10%MOD; 45 ans=ans+(tmp+c2[n-j]*shi%MOD)*s[i]%MOD; 46 } 47 } 48 printf("%lld\n",ans%MOD); 49 return 0; 50 }