原题: http://fastvj.rainng.com/problem/Gym-102174J
题意:
n长度的所有只有±号的式子的结果之和
解析:
x+b和x-b对应,显然任意一个带有符号的式子找得到一个相反符号的式子,所以只需要累加所有式子的第一个数字即可。
用dp[3]表示后半部分长度为3的方案数(+00、-01、+19),这个dp转移很简单:区分最后一个位置是符号还是数字,两种都可以加数字,但是只有最后为数字才可以加符号。
再看下面递推式:
一位数后面带两个位置的情况(第三列第一个)为
,到了n=4时,变成了
。对前式扩大100倍得:
,差了
。
而两位数带两个位置的情况的改变为:
,乘100后差了
。
用
表示i长度的答案,sum代表还差的部分。
那么
。
还要加上新的部分:
。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn=500009;
const LL mod=998244353;
LL ans[maxn];
LL dp[maxn][2];
void init(){//0 最后是符号
dp[0][0]=dp[0][1]=1;
dp[1][0]=2;dp[1][1]=0;
for(int i=2;i<=5e5;i++){
dp[i][1]=(dp[i-1][0]+dp[i-1][1])*10%mod;
dp[i][0]=dp[i-1][1]*2%mod;
}
ans[1]=45,ans[2]=4950,ans[3]=500400;
LL sum=(90000/2+900/2*dp[2][1])%mod;
for(int i=4;i<=5e5;i++){
ans[i]=(ans[i-1]*100+sum)%mod;
sum=sum*10%mod;
ans[i]=(ans[i]+45*dp[i-1][1])%mod;
sum=(sum+450*dp[i-1][1])%mod;
}
}
int main(){
init();
int t;scanf("%d",&t);
while(t--){
int n;scanf("%d",&n);
printf("%lld\n",ans[n]);
}
}