[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\) 的块的方案数。
转移:
时间复杂度 \(\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';
}

浙公网安备 33010602011771号