表 达 式 求 值 表达式求值 表达式求值
正 解 部 分 \color{red}{正解部分} 正解部分
按顺序扫表达式, 记录四个状态,
S
:
上
一
个
加
号
前
的
总
和
S: 上一个加号前的总和
S:上一个加号前的总和
M
:
上
一
个
加
号
到
最
后
一
个
乘
号
为
止
的
乘
积
M: 上一个加号到最后一个乘号为止的乘积
M:上一个加号到最后一个乘号为止的乘积
T
:
上
一
个
加
号
之
后
的
运
算
结
果
T: 上一个加号之后的运算结果
T:上一个加号之后的运算结果
e
:
1
e: 1
e:1
当前位置的字符为 c i c_i ci,
c
i
=
′
+
′
:
(
S
,
M
,
T
,
e
)
→
(
S
+
T
,
e
,
0
,
e
)
c_i =\ '+':\ \ \ \ \ (S, M, T, e) \rightarrow (S+T, e, 0, e)
ci= ′+′: (S,M,T,e)→(S+T,e,0,e)
c
i
=
′
×
′
:
(
S
,
M
,
T
,
e
)
→
(
S
,
T
,
0
,
e
)
c_i =\ '\times':\ \ \ \ \ (S,M,T,e) \rightarrow (S, T, 0, e)
ci= ′×′: (S,M,T,e)→(S,T,0,e)
c
i
=
数
字
k
:
(
S
,
M
,
T
,
e
)
→
(
S
,
M
,
10
T
+
k
M
,
e
)
c_i =\ 数字k: (S, M, T, e) \rightarrow (S, M, 10T+kM, e)
ci= 数字k:(S,M,T,e)→(S,M,10T+kM,e)
矩阵快速幂 加速转移, 最后 S + T S+T S+T 即为答案 .
实 现 部 分 \color{red}{实现部分} 实现部分
#include<bits/stdc++.h>
#define reg register
const int mod = 998244353;
struct Matrix{
int C[5][5];
Matrix(){ memset(C, 0, sizeof C); }
} add, mul, num, Ans;
Matrix modify(const Matrix &a, const Matrix &b){
Matrix res;
for(reg int i = 1; i <= 4; i ++)
for(reg int j = 1; j <= 4; j ++)
for(reg int k = 1; k <= 4; k ++)
res.C[i][j] = (1ll*res.C[i][j] + (1ll*a.C[i][k]*b.C[k][j]%mod)) % mod;
return res;
}
Matrix Ksm(Matrix a, int b){
Matrix res;
for(reg int i = 1; i <= 4; i ++) res.C[i][i] = 1;
while(b){
if(b & 1) res = modify(res, a);
a = modify(a, a); b >>= 1;
}
return res;
}
int N;
int r;
char s[20];
void Work(){
scanf("%d%s", &r, s+1);
int len = strlen(s+1);
Matrix Mmp;
for(reg int i = 1; i <= 4; i ++) Mmp.C[i][i] = 1;
for(reg int i = 1; i <= len; i ++){
if(s[i] == '+') Mmp = modify(Mmp, add);
else if(s[i] == '*') Mmp = modify(Mmp, mul);
else num.C[2][3] = s[i]-'0', Mmp = modify(Mmp, num);
}
Mmp = Ksm(Mmp, r); Ans = modify(Ans, Mmp);
}
int main(){
add.C[1][1] = add.C[3][1] = add.C[4][2] = add.C[4][4] = 1;
mul.C[1][1] = mul.C[3][2] = mul.C[4][4] = 1;
num.C[1][1] = num.C[2][2] = num.C[4][4] = 1, num.C[3][3] = 10;
Ans.C[1][2] = Ans.C[1][4] = 1; //
scanf("%d", &N);
for(reg int i = 1; i <= N; i ++) Work();
Ans = modify(Ans, add);
printf("%d\n", Ans.C[1][1]);
return 0;
}