タイトル説明
所定の長さ\(\ N-)文字列は、非負整数与えられ\(Kを\) 、文字列の途中に添加する必要が\(K \) $番目の\(+ \)「の数、にテーブル
そのような"として表現\(1000101 \)は "は、2つの追加\(+ \)になることがあり、数字を" \(10 + 001 + 01 \) "または" \(1 + 01 + 1000年\) "、発現しているの値(\ 12 \)と\(1002 \) 。
式のプログラムは、すべての付加価値のプラスとどのくらいを尋ねました。
入力
二つの整数\(N-、K \) 、文字列S $ $ \((0 <K = <N - 。<= 1E5)\)
出力
整数型の$十億七の$
サンプル入力
3 1
108
3 2
108
サンプル出力
27
9
カウント\(DP \)
まず第一に、確かに各番号の貢献度を計算されたデータ範囲のあまりを確認します。
では、どのような貢献を計算するのですか?
所与のトピック文字列のための\(S \)として左から右に、各桁を順次\(A_ {N-1} 、A_ {N-2} ... A_ {1}、A_0 \) 。
今、私たちがしなければならない(A_tとの\を)\貢献を議論するために、。
\(A_tと\)正しい\(T \)の位置に加え、合計ながら配置することができる\(N-1 \)位置プラス記号。
もし\(A_tと\)最初の位置の右プラス配置、\(A_tとは\)ビット、および通りである\(N-2 \)の空孔、\(1-K \) 、プラス記号合計\(C(K-1、 N-2)\) プログラムの種類。
寄与する\(C ,. 1-N-(1-K)* 10 ^ {} * A_tと0 \) 。
もし\(A_tと\)プラス記号、右側の位置に空第二の位置は、\(A_tと\) 10であり、\(N-3 \)空孔、\(1-K \ )プラス記号の合計\(C(K-1、 N-3)\) プログラムの種類。
貢献\(C(1-K、2-N-)* 10 ^ {} * A_tと1 \)。
などなど、
場合\(A_tとの\)右側には空である、にその後寄与\(C(K、NT-2){T} * 10 * A_tと^ \) 。
したがって、\(A_tと\)この番号への寄与である(10 ^ {T}(\ + \和^ {T} _ {J = 0} 10 ^ {J} * C(* C(K、NT-2) 。1-K、2-NJ))A_tと* \) 。
私たちは最初に得ることができる\(Iは\)寄与計算された数の\(a_iを= 10 ^ {I } * C(K、NI-2)+ \和^ {I} _ {J = 0} 10 ^ { * C} J(1-K、2-NJ)\)。
最後に、\(ANS = \ ^ {N-SUM-I 1 = 0}} _ {a_iを* a_iを\)。
コードは以下の通りです
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define int long long
#define reg register
#define Raed Read
#define clr(a,b) memset(a,b,sizeof a)
#define Mod(x) (x>=mod)&&(x-=mod)
#define debug(x) cerr<<#x<<" = "<<x<<endl;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define rep(a,b,c) for(reg int a=(b),a##_end_=(c); a<=a##_end_; ++a)
#define ret(a,b,c) for(reg int a=(b),a##_end_=(c); a<a##_end_; ++a)
#define drep(a,b,c) for(reg int a=(b),a##_end_=(c); a>=a##_end_; --a)
#define erep(i,G,x) for(int i=(G).Head[x]; i; i=(G).Nxt[i])
#pragma GCC target("avx,avx2,sse4.2")
#pragma GCC optimize(3)
inline int Read(void) {
int res=0,f=1;
char c;
while(c=getchar(),c<48||c>57)if(c=='-')f=0;
do res=(res<<3)+(res<<1)+(c^48);
while(c=getchar(),c>=48&&c<=57);
return f?res:-res;
}
template<class T>inline bool Min(T &a, T const&b) {
return a>b?a=b,1:0;
}
template<class T>inline bool Max(T &a, T const&b) {
return a<b?a=b,1:0;
}
const int N=1e5+5,M=1e6+5,mod=1e9+7;
bool MOP1;
int Fac[N],Inv[N];
inline int Pow(int x) {
int res=1,y=mod-2;
while(y) {
if(y&1)res=(res*x)%mod;
x=(x*x)%mod,y>>=1;
}
return res;
}
inline int C(int x,int y) {
if(!x)return 1;
return (Fac[y]*((Inv[x]*Inv[y-x])%mod))%mod;
}
int A[N],Pow_10[N];
char S[N];
bool MOP2;
inline void _main() {
int n=Read(),k=Read(),Ans=0,tot=0;
scanf("%s",S),Fac[0]=Pow_10[0]=Inv[0]=1;
if(!k) {
int Ans=0;
ret(i,0,n)Ans=(Ans*10+(S[i]^48))%mod;
printf("%lld\n",Ans);
return;
}
rep(i,1,n) {
Fac[i]=(Fac[i-1]*i)%mod;
Pow_10[i]=(Pow_10[i-1]*10)%mod;
Inv[i]=Pow(Fac[i]);
}
A[0]=C(k-1,n-2);
int P=n-k-1;
rep(i,0,P)A[i]=(A[i-1]+Pow_10[i]*C(k-1,n-i-2))%mod;
rep(i,P+1,n)A[i]=A[i-1];
rep(i,0,P)A[i]=(A[i]+Pow_10[i]*C(k,n-i-2));
ret(i,0,n)Ans=(Ans+(S[i]^48)*A[n-i-1])%mod;
printf("%lld\n",Ans);
}
signed main() {
_main();
return 0;
}