どこでもCodeForces-520Eプラス

タイトル説明

所定の長さ\(\ 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;
}

おすすめ

転載: www.cnblogs.com/dsjkafdsaf/p/11402180.html