如果以下条件成立,我们就把一个整数序列称为美丽:
- 它的长度至少为 3 ;
- 除第一个元素外,每个元素的左边都有一个比它小的元素;
- 除最后一个元素外,每个元素的右边都有一个比它大的元素;
回顾一下,子序列是指在不改变其余元素顺序的情况下,通过删除某些元素而从另一个序列中得到的序列。
给你一个大小为 n 的整数数组 a ,其中 每个元素都从 1 到 3。你的任务是计算数组 a 中优美子序列的个数。由于答案可能很大,请打印出它的模数 998244353。
解:
由题:可行的方案必须是类似1 2 2 2 2 … 3这种的。1开头,3结尾,中间有非零0个2。
每次输入一个新的数的时候,如果这个数是2,那么假设前面有a个1,此时这个2可以接到前面a个1的后面。假设b为此时前面形如1 2 2 2…的序列的个数,那么同时此位置的2也可以接到前面b个后面。例如1 2 2,此时a=1,b=3。当再次遇到2的时候,组成1 2(q) 2(w) 2(x),此时b的个数为x接到前面a个1的后面这种可能加原先b种可能以及,先前1 q,1 w,1 q w的后面。故遇到2的时候,b=b*2+a。
遇到3的时候,可以直接接到前面b种可能的后面即可。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define uint unsigned int
#define pii pair<int,int>
const int mod = 998244353;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, 1, 0, -1};
void solve() {
int n;
cin >> n;
vector<int> arr(n + 1);
int a = 0, b = 0;
int ans = 0;
for (int i = 1; i <= n; i++) {
cin >> arr[i];
if (arr[i]==1) a++;
else if (arr[i]==2){
b=(b*2%mod+a)%mod;
}else ans=(ans+b)%mod;
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}