ARC 187 C

SFlyer發表於2024-11-18

首先扔出一個結論,如果 \(Q\) 中沒有 \(-1\),那麼答案是 \(2^k\),其中 \(k=\sum_{i=2}^n [Q_i=\max(P_{1\sim i})]\)。考慮證明。

\(Q_i=\max(P_{1\sim i})\) 的位置(包含 \(i=1\))是 \(a_1\sim a_{k+1}\)。那麼設 \(f_i\)\(1\sim a_i\) 的答案,顯然 \(f_1=1\)。考慮 \(Q_{a_i}\) 放哪。我們發現可以插在前面一個字首最大值 \(a_j\) 的正後方,而 \(a_j+1\sim a_i\) 是啥都固定了,並且 \(1\sim a_j\)\(f_j\)。那麼得出 \(f_i=\sum_{j=1}^{i-1}f_j\),則 \(f_1=1,f_2=1,f_3=1+1=2,f_4=1+1+2=4,\cdots, f_{k+1}=2^k\)

因此設 \(f_{i,j}\) 為前 \(i\) 位,現在 \(\max\)\(j\) 的答案即可。為了方便,設 \(Q_0=0\),最後答案是 \(\frac{f_{n,n}}{2}\)

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 5e3+3;
const ll mod = 998244353;
const ll i2 = (mod+1)/2;

int n,m,a[N],vis[N],t[N];
ll f[N],s[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	for (int i=1; i<=n; i++){
		cin>>a[i];
		if (a[i]!=-1) vis[a[i]]=1;
	}
	for (int i=1; i<=n; i++){
		t[i]=t[i-1]+(vis[i]==0);
	}
	f[0]=1;
	for (int i=1,c=0; i<=n; i++){
		if (a[i]!=-1){
			for (int j=1; j<=a[i]; j++){
				f[j]=(f[j]+f[j-1])%mod;
				f[j-1]=0;
			}
			f[a[i]]=(f[a[i]]+f[a[i]])%mod;
		}
		else{
			s[0]=f[0];
			for (int j=1; j<=n; j++){
				s[j]=(f[j]+s[j-1])%mod;
			}
			f[0]=0;
			for (int j=1; j<=n; j++){
				f[j]=(f[j]*(t[j]-c)%mod+s[j-1]*2*(!vis[j]))%mod;
			}
			c++;
		}
		if (i!=n) f[n]=0;
	}
	cout<<f[n]*i2%mod<<"\n";
	return 0;
}

相關文章