本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目链接:
本题不要计算序列a的价值,因为从这个方面考虑很难做出来。
应该从取序列中的哪些值才能使序列a的价值不变来考虑。
对于三个数来讨论:
- 或时
删除中间的数,序列的价值不会变化。如果中间相同的数有k个,情况数为
- 或时
删除中间的值,序列价值会发生变化,所以不能删除。但是如果中间的值有多个相等的话,要至少留一个值即可。如果相等数的个数为k,则情况数为(去除为空的情况)
接下来,就是对中间的相同的数进行讨论了
把相等的数看成一个连通块,设为
-
如果满足 或(且要满足),则区间的数可以全部删除,不影响价值,这样的区间对答案贡献有种方案。
-
否则区间的数必须保留一个,这样的区间对答案贡献 种方案。把所有区间的贡献连乘起来就是答案。
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e5 + 5, mod = 998244353;
vector<ll> fac(N);
void solve()
{
int n;
cin >> n;
vector<int> a(n);
for(auto &i : a) cin >> i;
ll res = 1;
for(int i = 0, j = 0; i < n; i++)
{
j = i;
while(j < n - 1 && a[j + 1] == a[i]) j++;
if(i - 1 >= 0 and j + 1 < n and (a[i - 1] < a[i] && a[i] < a[j + 1] || a[i - 1] > a[i] && a[i] > a[j + 1]))
res = res * fac[j - i + 1] % mod;
else res = res * (fac[j - i + 1] - 1) % mod;
i = j;
}
cout << res << "\n";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
fac[0] = 1;
for(int i = 1; i < N; i++)
fac[i] = fac[i - 1] * 2 % mod;
int t;
cin >> t;
// t = 1;
while(t--) solve();
return 0;
}