专栏文章
题解:CF1067A Array Without Local Maximums
CF1067A题解参与者 9已保存评论 8
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mio0ex1t
- 此快照首次捕获于
- 2025/12/02 11:19 3 个月前
- 此快照最后确认于
- 2025/12/02 11:19 3 个月前
这题很显然吧。设 ,对大小 下手即可。然后转移状态时考虑大小为 的可行性,若 确定强制转移即可。
这个时候我们发现转移过程有点冗余了,每次暴力 的大小转移,需要 ,不妨考虑加一维表示相对大小,然后通过前缀和来优化掉冗余的转移。那么优化到 可过。
具体来讲,设 表示第 位大小为 的方案数,而 分别表示 、、。
- 对于状态 ,显然 与 大小关系如何都无所谓,因为 帮助 完成了限制条件,故 ;
- 对于状态 ,与状态 一样不用考虑前者的相对大小,;
- 对于状态 ,显然只能从 转移过来,不然 就无法满足限制条件了,故 。
这个时候不难发现,对 做一个前缀和,对 做一个后缀和,就可以 转移一次状态。
总体时间复杂度 。
评测记录 #336937092
CPP#include <bits/stdc++.h>
#define int long long
#define lint long long
#define endl '\n'
using namespace std;
const int N = 1e5+5;
const int M = 2e2+5;
const int mod = 998244353;
int n,m,a[N];
int pre[M],suf[M];
int f[N][M][3];
inline void init(int i){
for(int j = 1; j <= m; j++){
pre[j] = pre[j-1] + f[i-1][j][0] + f[i-1][j][1] + f[i-1][j][2];
pre[j] %= mod;
}
for(int j = m; j >= 1; j--){
suf[j] = suf[j+1] + f[i-1][j][1] + f[i-1][j][2];
suf[j] %= mod;
}
}
inline void check(int i,int l,int r){
init(i);
for(int j = l; j <= r; j++){
f[i][j][0] = pre[j-1],f[i][j][2] = suf[j+1];
f[i][j][1] = f[i-1][j][0] + f[i-1][j][1] + f[i-1][j][2];
f[i][j][1] %= mod;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
// freopen("app.in","r",stdin);
// freopen("app.out","w",stdout);
m = 200;
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
if(a[1] == -1)
for(int j = 1; j <= m; j++)
f[1][j][0] = 1;
else f[1][a[1]][0] = 1;
for(int i = 2; i <= n; i++){
if(a[i] == -1) check(i,1,m);
else check(i,a[i],a[i]);
}
int ans = 0;
if(a[n] == -1){
for(int j = 1; j <= m; j++){
ans += f[n][j][1] + f[n][j][2];
ans %= mod;
}
}else ans = (f[n][a[n]][1] + f[n][a[n]][2]) % mod;
cout << ans << endl;
return 0;
}
相关推荐
评论
共 8 条评论,欢迎与作者交流。
正在加载评论...