价值序列
题意:
给出长度为
n
n
n 的整数数组
a
1
,
a
2
,
…
,
a
n
a_{1}, a_{2}, \ldots, a_{n}
a1,a2,…,an ,定义序列的价值为
∑
i
=
1
n
−
1
∣
a
i
−
a
i
+
1
∣
\sum_{i=1}^{n-1}\left|a_{i}-a_{i+1}\right|
∑i=1n−1∣ai−ai+1∣ 。
当数组长度为 1 时,价值认为是 0 。
求有多少不同的
1
≤
i
1
<
i
2
<
…
<
i
k
≤
n
(
1
≤
k
≤
n
)
1 \leq i_{1}<i_{2}<\ldots<i_{k} \leq n(1 \leq k \leq n)
1≤i1<i2<…<ik≤n(1≤k≤n) 满足子序列
a
i
1
,
a
i
2
,
…
,
a
i
k
a_{i 1}, a_{i 2}, \ldots, a_{i k}
ai1,ai2,…,aik 的价值等于
a
1
,
a
2
,
…
,
a
n
a_{1}, a_{2}, \ldots, a_{n}
a1,a2,…,an 的价值。
由于答案可能很大,对答案 mod
998244353
998244353
998244353。
思路:
首先说一个结论:删除一个数,价值必定不增。
证明可以用归纳法,对于
n
≤
2
n \leq 2
n≤2 显然。
对于
n
>
2
n>2
n>2 ,如果删除一个
a
i
−
1
≤
a
i
≤
a
i
+
1
a_{i-1} \leq a_{i} \leq a_{i+1}
ai−1≤ai≤ai+1 的位置
i
i
i ,价值不变,如果删除
a
i
−
1
≥
a
i
≥
a
i
+
1
a_{i-1} \geq a_{i} \geq a_{i+1}
ai−1≥ai≥ai+1 的位置
i
i
i 价值也不变。如果删除
a
i
−
1
≤
a
i
≥
a
i
+
1
a_{i-1} \leq a_{i} \geq a_{i+1}
ai−1≤ai≥ai+1 或
a
i
−
1
≥
a
i
≤
a
i
+
1
a_{i-1} \geq a_{i} \leq a_{i+1}
ai−1≥ai≤ai+1 ,答案只可能减少,删除一个数后
n
n
n 的 规模减1,由归纳法结论得证。
接下来,考虑删除哪些数答案不会变。
把相等的数看成一个连通块,设为
[
i
,
j
]
[i, j]
[i,j] 。
如果满足
a
i
−
1
<
a
i
=
…
=
a
j
<
a
j
+
1
a_{i-1}<a_{i}=\ldots=a_{j}<a_{j+1}
ai−1<ai=…=aj<aj+1 或
a
i
−
1
>
a
i
=
…
=
a_{i-1}>a_{i}=\ldots=
ai−1>ai=…=
a
j
>
a
j
+
1
a_{j}>a_{j+1}
aj>aj+1 (且要满足
i
>
1
,
j
<
n
i>1, j<n
i>1,j<n ),则区间
[
i
,
j
]
[i, j]
[i,j] 的数可以全部删除,不影响价值,这样的区间对答案 贡献有
2
j
−
i
+
1
2^{j-i+1}
2j−i+1 种方案。
否则区间
[
i
,
j
]
[i, j]
[i,j] 的数必须保留一个,这样的区间对答案贡献
2
j
−
i
+
1
−
1
2^{j-i+1}-1
2j−i+1−1 种方案。把所有区间的贡献连乘起来就是答案。
——摘自牛客网
Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 200010, mod = 998244353;
int T, n, m;
int a[N];
bool pd(int i, int j)
{
if(i==1 || j==n) return 0;
if(a[i-1]<a[i] && a[j+1]>a[j]) return 1;
if(a[i-1]>a[i] && a[j+1]<a[j]) return 1;
return 0;
}
int qmi(int x, int y)
{
int ans = 1;
while(y)
{
if(y & 1) ans = ans*x%mod;
x = x*x%mod;
y >>= 1;
}
return ans;
}
signed main(){
Ios;
cin>>T;
while(T--)
{
int ans = 1;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
int j = i;
while(a[j+1] == a[i]) j++;
if(pd(i, j)) ans = ans * qmi(2, j-i+1) % mod;
else ans = ans * (qmi(2, j-i+1) - 1) % mod;
i = j;
}
cout << ans << endl;
}
return 0;
}