T1:显然直接斜着做前缀和就好了。
比赛时我有一个地方没有开long long,所以90分。大数据不能代替检查和对拍。
T2:这题有很强的思维。
设f[i][j][0/1]表示前i位,是否顶到上限(0/1)的数字j的个数。注意这里的个数是算上所有情况的。
之所以可以这样设dp是因为我们最终只用关心所有情况合起来时每个数字出现的总次数,至于每个数字具体在哪一个数中出现并不重要。
然后考虑转移f。
首先我们要把之前的f都加上,即f[i+1][j][0]+=f[i][j][0]*10(前i位有f[i][j][0]个数字,第i+1位可以填0~9共10个数字,所以有10种情况)。f[i][j][1]同理讨论。
然后我们要算上i+1位的新的贡献。对于f[i+1][j][1],其实i+1位的贡献就等于1(在j=a[i+1]时),这个很好理解。对于f[i+1][j][0],i+1位的贡献就是a[1~i]-1,即前面的数的方案数。
其实这些方程式都不是绝对的,都要因具体的j和a[i+1]而定。
那么现在就假设我们已经算出了f,然后要求答案。对于一个第i位填j,前面的数对它的贡献就是sum(f[i-1][x][0/1])(x>j),然后这个贡献还要乘上它后面的可填的数的个数(即10^(n-i)或a[i+1~n]+1)。
至此,这题我们就做出来了。
细节较多,贴一下代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define ll long long
#define MAXN 500010
#define mod 998244353
ll f[MAXN][11][2],a[MAXN],s[MAXN],b[MAXN],T,num,n,ans;
char a1[MAXN];
ll sqr(ll x,ll y)
{
ll j=x,s=1,w=y;
while(w>=1)
{
if(w%2==1)s=(s*j)%mod;
j=(j*j)%mod;w/=2;
}
return s;
}
ll dp()
{
ll i,j,k,x,w0,w1;
memset(f,0,sizeof(f));
for(i=0;i<a[1];i++)f[1][i][0]=1;
f[1][a[1]][1]=1;
s[1]=a[1];
for(i=1;i<n;i++)
{
for(j=0;j<=9;j++)
{
if(j>=a[i+1])f[i+1][j][0]=(f[i+1][j][0]+f[i][j][0]*10+f[i][j][1]*a[i+1]+s[i])%mod;
else f[i+1][j][0]=(f[i+1][j][0]+f[i][j][0]*10+f[i][j][1]*a[i+1]+s[i]+1)%mod;
if(j==a[i+1])f[i+1][j][1]=(f[i+1][j][1]+f[i][j][1]+1)%mod;
else f[i+1][j][1]=(f[i+1][j][1]+f[i][j][1])%mod;
}
s[i+1]=(s[i]*10+a[i+1])%mod;
}
s[n+1]=0;
s[n]=a[n];
for(i=n-1;i>=1;i--){s[i]=(s[i+1]+a[i]*b[n-i])%mod;}
ans=0;
for(i=2;i<=n;i++)
{
w0=0;w1=0;
for(j=9;j>=0;j--)
{
if(j<a[i])ans=(ans+(w0+w1)*b[n-i])%mod;
else
{
ans=(ans+w0*b[n-i])%mod;
if(j==a[i])ans=(ans+w1*(s[i+1]+1))%mod;
}
w0=(w0+f[i-1][j][0])%mod;
w1=(w1+f[i-1][j][1])%mod;
}
}
return ans;
}
int main()
{
//freopen("pair.in","r",stdin);
//freopen("pair.out","w",stdout);
ll i,j,w;
scanf("%lld %lld\n",&T,&num);
b[0]=1;
for(i=1;i<=500000;i++)b[i]=b[i-1]*10%mod;
while(T>=1)
{
scanf("%s ",a1);
n=strlen(a1);
memset(a,0,sizeof(a));
for(i=1;i<=n;i++)a[i]=a1[i-1]-'0';
a[n]--;
i=n;
while(a[i]<0){a[i]+=10;a[i-1]--;i--;}
w=-dp();
scanf("%s\n",a1);
n=strlen(a1);
for(i=1;i<=n;i++)a[i]=a1[i-1]-'0';
w=w+dp();
printf("%lld\n",(w+mod)%mod);
T--;
}
}
T3:题解待更新。