[Ucup3 Stage of Haidian Huangzhuang] Twenty-two

设全局 \(\texttt{chkmin}\) 的参数最小值 \(c_0=\min\{c_1,c_2,\dots,c_m\}\)。

则在 \(\texttt{chkmin}\: c_0\) 之前执行的所有 \(\texttt{chkmin}\) 操作无效。

而在其后的 \(\texttt{chkmin}\:T\) 则可以把更大的 \(\texttt{chkmax}\) 压成 \(T\),从而构造出权值 \(T\) 的层。

考虑一个参数为 \(t\) 的区间 \(\texttt{chkmax}\),以及一个参数为 \(T\) 的全局 \(\texttt{chkmin}\)。

若先操作前者,则对于区间内数 \(x\),效果为:\(x\leftarrow\min(\max(x,t),T)\)。

因此,若 \(t>T\),就等价于把整个区间赋值为 \(T\)。

若 \(t\le T\),也等价于先 \(\texttt{chkmin}\:T\) 再 \(\texttt{chkmax}\:t\)。

其实初始值是无效的,对于位置 \(i\):

  • \(a_i<c_0\)
    • 若存在一个参数 \(\ge c_0\) 的区间 \(\texttt{chkmax}\) 覆盖,则 \(a_i\) 必然改变。
    • 否则最终值由 \(<c0\)​ 的 \(\texttt{chkmax}\) 操作决定,最终值固定。
  • \(a_i\ge c_0\),则会被 \(\texttt{chkmin}\: c_0\) 覆盖。

现在问题变成:

初始所有位置均为 \(c_0\)。

有若干区间 \(\texttt{chkmax}\),每个区间可以在某个权值 \(T\) 上使用,仅当:

  • 该区间 \(\texttt{chkmax}\) 参数 \(t=T\) 或者 \(t>T\) 且 \(T\) 是某个全局 \(\texttt{chkmin}\) 的参数。

每个区间可以选择是否生效(通过放在 \(\texttt{chkmin}\:c_0\) 前面使其无效)。

最终每个位置的值等于覆盖它的所有生效区间的最大权值,问能构造出多少种不同的最终序列?

按权值从高到低处理,设当前处理权值 \(T\),且所有 \(>T\) 的已处理完。

考虑一个区间可以同时放置某些权值的块(类似一棵树),满足:外层权值低,内层权值高,同一权值的块不能嵌套。

设:

  • \(g_{l,r}\) 表示在区间 \([l,r]\) 内,只使用权值 \(>T\) 的块且允许空位的方案数。

  • \(f_{l,r}\) 表示区间 \([l,r]\) 被一个完整的权值 \(T\) 块覆盖,且内部可任意放置任意放置权值 \(>T\) 的块的方案数。

转移:

\[g_{l,r}=f_{l,r}+\sum_{i=l}^{r}{g_{l,i-1}f_{i+1,r}} \]

\[f_{l,r}=g_{l,r}-\sum_{\substack{i\in[l,r] \\ i \text{ 未被 }T\text{ 覆盖}}}{f_{l,i-1}g_{i+1,r}} \]

时间复杂度 \(\mathcal O(n^4)\)。

点击查看代码
#include<bits/stdc++.h>
#define FASTIO ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define rep(i,l,r) for(int i=(l); i<=(r); ++i)
#define drep(i,r,l) for(int i=(r); i>=(l); --i)
using namespace std;
const int N=155,P=998244353;
int n,m,q,c0=N,c,p[N],L[N],R[N],t[N],d[N],f[N][N],g[N][N];
inline void inc(int&x,int y) {x-=(x+=y)<P?0:P;}
void init(auto&f) {memset(f,0,sizeof f);rep(i,0,n) f[i+1][i]=1;}
signed main() {
	FASTIO;
	cin>>n>>m>>q,init(f);
	rep(i,1,n) cin>>c;
	rep(i,1,m) cin>>c,c0=min(c0,c),p[c]=1;
	rep(i,1,q) cin>>L[i]>>R[i]>>t[i];
	L[++q]=1,R[q]=n,t[q]=c0;
	drep(T,n,c0) {
		init(g);
		rep(r,1,n) drep(l,r,1) {
			g[l][r]=f[l][r];
			rep(i,l,r) inc(g[l][r],1LL*g[l][i-1]*f[i+1][r]%P);
		}
		init(f);
		rep(r,1,n) drep(l,r,1) {
			f[l][r]=g[l][r],memset(d,0,sizeof d);
			rep(i,1,q) if(l<=L[i]&&R[i]<=r&&(t[i]==T||p[T]&&t[i]>T)) ++d[L[i]],--d[R[i]+1];
			rep(i,l,r) if(!(d[i]+=d[i-1])) inc(f[l][r],P-1LL*f[l][i-1]*g[i+1][r]%P);
		}
	}
	cout<<f[1][n]<<'\n';
}
posted @ 2026-08-13 15:14  in-bustle  阅读(13)  评论(0)    收藏  举报