[ARC206C] Tree Sequence 题解
简单找性质题。
对于所有区间这个限制很严格,尝试放松限制。考察区间长度
于是就可以 DP 了:设
代码中的数组是 0-indexed 的。
放代码:
#include<bits/stdc++.h>
using namespace std;
const int P=998244353;
inline int add(int x,int y){
int s=x+y; if(s>=P)s-=P; return s;
}
inline void self_add(int &x,int y){
if((x+=y)>=P)x-=P;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n; cin>>n;
vector<int> a(n);
for(auto &i:a)cin>>i,i-=i>0;
vector<int> f(2); f[1]=1;
for(int i=0;i<n;i++){
vector<int> g(2);
if(~a[i]){
if(a[i]==i-1)self_add(g[0],add(f[0],f[1]));
// 往前满足条件
else if(a[i]==i+1)self_add(g[1],f[1]);
// 往后满足条件
else self_add(g[0],f[1]);
// 上一个元素往后的条件必须满足,这个元素往前后的条件都一定不满足
} // a[i] 的值确定
else{
// 类似于前面,只是每种转移多了一个系数
if(i)self_add(g[0],add(f[0],f[1]));
self_add(g[0],1ll*f[1]*(n-((bool)i)-(i<n-1))%P);
if(i+1<n)self_add(g[1],f[1]);
} // a[i] 的值可以随便选
f=move(g);
}
cout<<add(f[0],f[1])<<endl;
return 0;
}