Counting Cute Arrays
Mier_Samuelle · · 题解
提供一种不太一样的刻画方式。
考虑限制
-
- 对于任意
j<k<i ,均有A_k>A_i 。
将限制
接下来需对这个条件计数。对每个
那么实际上,最终整个过程可以刻画为:若
自底向上对每个区间跑一遍这个 dp,最后把最上层区间拉出来再跑一遍。前缀和优化,复杂度
:::success[Code]{open}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 5010;
const int MOD = 998244353;
struct Interval{
int l, r, ind;
vector <int> adj;
};
bool cmp(Interval x, Interval y){
if (x.l != y.l){
return x.l < y.l;
}
return x.r > y.r;
}
void add(int &x, int y){
x += y;
if (x >= MOD) x -= MOD;
return;
}
int a[MAXN], f[MAXN][MAXN], n;
int calc(vector <int> &o){
int k = (int)o.size() - 1;
for (int j = 1; j <= k; j++){
f[0][j] = 0;
}
f[0][0] = 1;
for (int i = 1; i <= k; i++){
for (int j = 0; j <= k; j++){
f[i][j] = 0;
}
if (o[i] == 1){
for (int j = 1; j <= i; j++){
f[i][j] = f[i - 1][j - 1];
}
}
else{
int sum = 0;
for (int j = i; j >= 1; j--){
add(sum, f[i - 1][j - 1]);
f[i][j] = sum;
}
}
}
int ans = 0;
for (int j = 0; j <= k; j++){
add(ans, f[k][j]);
}
return ans;
}
void solve(){
cin >> n;
vector <Interval> s;
int cnt = 0;
for (int i = 1; i <= n; i++){
cin >> a[i];
}
for (int i = 1; i <= n; i++){
if (a[i] >= i){
cout << 0 << "\n";
return;
}
if (a[i] != -1){
s.push_back({a[i], i, cnt++});
}
}
s.push_back({0, n + 1, cnt++});
sort(s.begin(), s.end(), cmp);
stack <int> st;
for (int i = 0; i < cnt; i++){
while (!st.empty() && s[st.top()].r < s[i].r){
if (s[st.top()].r > s[i].l){
cout << 0 << "\n";
return;
}
st.pop();
}
if (!st.empty()){
s[st.top()].adj.push_back(i);
}
st.push(i);
}
ll ans = 1;
for (int i = 0; i < cnt; i++){
vector <int> o;
o.push_back(0);
int lst = s[i].l + 1;
for (int u : s[i].adj){
if (s[u].l - lst + 1 < 0){
cout << 0 << "\n";
return;
}
for (int j = 1; j <= s[u].l - lst + 1; j++){
o.push_back(0);
}
o.push_back(1);
lst = s[u].r + 1;
}
if (s[i].r - lst < 0){
cout << 0 << "\n";
return;
}
for (int j = 1; j <= s[i].r - lst; j++){
o.push_back(0);
}
ans = ans * calc(o) % MOD;
}
cout << ans << "\n";
return;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--){
solve();
}
return 0;
}
:::