题目链接
题意分析
考试的时候想到了按位分析 但是由于计算公式过于麻烦 所以就咕了
现在考虑一下按位分析怎么做
我们对于当前第\(i\)位可以做的贡献
假设分割之后它处在第\(j\)位上 那么他的贡献就是
\[d*10^j*num \]\(d\)表示第\(i\)位的数字 而\(num\)表示这样之后的划分方案数
所以接下来我们的任务就是如何计算\(num\)
①\(i+j<n\)
如果\(i+j<n\) 的话 那么由于我们最后最多划分成\(k\)段 所以考虑插板法 答案就是
\[\sum_{m=0}^{k-2}C_{n-j-2}^{m} \]②\(i+j=n\)
如果\(i+j=n\) 的话 那么由于我们最后最多划分成\(k\)段 所以考虑插板法 答案就是
\[\sum_{m=0}^{k-1}C_{n-j-1}^{m} \]对于\(i+j=n\) 我们可以直接计算入答案中
而对于\(i+j<n\) 我们可以采用倒序的方式不断累加 从而计算
\[\sum_{j=0}^{n-i-1}num=\sum_{j=0}^{n-i-1}\sum_{m=0}^{k-2}C_{n-j-2}^{m} \]那么关键问题就是如何计算\(\sum_{m=0}^{k-2}C_{n-j-2}^{m}\)以及\(\sum_{m=0}^{k-1}C_{n-j-1}^{m}\)
我们发现对应的格式是\(\sum_{i=0}^bC_a^i\)
所以 令
\[F(a,b)=\sum_{i=0}^bC_a^i \]同时 ,由于
\[C_{n+1}^m=C_{n}^m+C_{n}^{m-1} \] \[∴2F(a,b)=2C_a^0+2C_a^1+...+2C_a^b=C_a^0+C_{a+1}^1+...+C_{a+1}^{b}+C_{a}^{b}=C_{a+1}^0+C_{a+1}^1+...+C_{a+1}^{b}+C_{a}^{b}=F(a+1,b)+C_{a}^{b} \]所以我们可以得到一个线性的递推公式出来
\[F(a,b)=2F(a-1,b)-C_{a-1}^{b} \]这样的话就可以计算了
CODE:
#include<bits/stdc++.h>
#define M 1000611
using namespace std;
const long long mod=998244353;
int T,n,k;
char s[M];
long long ans,sum;
long long Pow[M],fac[M],inv[M];
long long Fa[M],Fb[M];
long long qpow(long long x,long long y)
{long long tmp=1;for(;y;y>>=1,x=x*x%mod) if(y&1) tmp=tmp*x%mod;return tmp;}
long long C(int x,int y)
{
if(x<y) return 0;
else return (fac[x]*inv[x-y]%mod)*inv[y]%mod;
}
int main()
{
// freopen("data.in","r",stdin);
scanf("%d",&T);
Pow[0]=fac[0]=inv[0]=1;
for(int i=1;i<=1000000;++i) Pow[i]=Pow[i-1]*10%mod;
for(int i=1;i<=1000000;++i) fac[i]=fac[i-1]*i%mod;
inv[1000000]=qpow(fac[1000000],mod-2);
for(int i=999999;i;--i) inv[i]=inv[i+1]*(i+1)%mod;
while(T--)
{
scanf("%d%s",&k,s+1);n=strlen(s+1);
sum=0;ans=0;
Fa[0]=1;Fb[0]=(k>=2 ? 1:0);
for(int i=1;i<=n;++i)
{
Fa[i]=(2*Fa[i-1]%mod-C(i-1,k-1)+mod)%mod;
Fb[i]=(2*Fb[i-1]%mod-C(i-1,k-2)+mod)%mod;
}
// for(int i=1;i<=n;++i) printf("%lld%c",Fa[i],(i==n ? '\n':' '));
// for(int i=1;i<=n;++i) printf("%lld%c",Fb[i],(i==n ? '\n':' '));
for(int i=n;i;--i)
{
if(i<n) sum=(sum+(Pow[n-i-1]*Fb[i-1]%mod))%mod;
ans=(ans+((Pow[n-i]*Fa[i-1]%mod+sum)%mod)*(s[i]-'0')%mod)%mod;
}
printf("%lld\n",ans);
}
return 0;
}