[ARC104F] Visibility Sequence
给一个长为 \(n\) 的数列 \(h_{1\dots n}\),第 \(i\) 项在 \([1,h_i]\) 中选一个数,得到数列 \(x_{1\dots n}\)。
再构造一个数列 \(p_{1\dots n}\),\(p_i=\max j(j<i,x_j>x_i)\),若不存在这样的 \(j\),\(p_i=-1\)。
求能构造出多少种 \(p\)。
\(n\leq 100,h_i\leq 10^5\)。
显然 \(h_i\) 可以很大,但是大于 \(n\) 的时候是没有意义的,因为我们只需要看 \(x\) 的相对大小。所以可以对 \(n\) 取 \(\min\)(因为算上 \(-1\) 之后至多有 \(n+1\) 个不同的值,为 \(h_i=n\) 的时候就已经能够保证这些值全部被取到)。
考虑 \(i\) 与 \(p_i\) 之间之间连边,如果 \(p_i=-1\) 不妨将其视作一个编号为 \(0\) 的点。容易发现构成了一颗树。将 \(0\) 号点视为树根,发现这棵树具有以下性质性质。
- 子树根的编号最小且 \(x\) 值大于其子树内所有点的 \(x\) 值,根据定义可以得到。
- 子树内点的标号连续,即不能出现 \(i<j<k<l\),\(p_k=i,p_l=j\) 的情况,容易发现 \(p_k=i\) 说明 \(x_i>x_k>x_j\),而 \(p_l=j\) 说明了 \(x_j>x_l>x_k\),两者矛盾。
- 子树内深度相同的节点(即兄弟节点)中,编号越大的节点 \(x\) 值越大(否则这些节点之间就会连边了)。
于是我们定义 \(f_{l,r,k}\) 为区间 \([l,r]\) 构成一颗以 \(l\) 为根的树且 \(h_l=k\) 的方案数,定义 $g_{l,r,k} $ 为期间 \([l,r]\) 构成了一个最大的数为 \(k\) 的森林的方案数。同时定义 \(sf\) 和 \(sg\) 为这 \(f,g\) 第三维的前缀和。得到转移:
\[f_{l,r,k}\gets g_{l+1,r,k-1} \quad k\leq h_l\\ g_{l,r,k}\gets f_{l,r,k}\quad k\leq h_l\\ g_{l,r,k}\gets g_{l,r,k} +\sum_{i=l}^{r-1} sg_{l,i,k}\times f_{i+1,r,k} \quad k\leq h_{i+1}\\ g_{l,r,k}\gets g_{l,i,k} +\sum_{i=1}^{r-1}g_{l,i,k}\times sf_{i+1,r,k-1}\quad k\leq h_{i+1} \]第一个和第二个式子表示 \(l\) 节点作为区间 \([l,r]\) 的树根。
第三个式子 \(f_{i+1,r,k}\) 需要保证森林中至少有一个点为 \(x=k\),同时也保证了不会算重。
第四个式子 \(sf_{i+1,r,k-1}\) 的 \(k-1\) 是为了保证第三条性质。
初始状态 \(f_{i,i,1}=g_{i,i,1}=1\),答案状态 \(sg_{1,n,n}\)。
具体实现见代码。
using namespace modulo;
using namespace FastIO;
int n,h[N];
ll f[N][N][N],g[N][N][N],sf[N][N][N],sg[N][N][N];
int main(){
n=read();
for(int i=1;i<=n;++i){
h[i]=read();
h[i]=min(h[i],n);
}
for(int i=1;i<=n;++i){
f[i][i][1]=g[i][i][1]=1;
for(int j=1;j<=n;++j)
sf[i][i][j]=sg[i][i][j]=1;
}
for(int len=2;len<=n;++len){
for(int l=1,r=len;r<=n;++l,++r){
for(int k=1;k<=h[l];++k)
f[l][r][k]=g[l][r][k]=g[l+1][r][k-1];
for(int i=l;i<r;++i){
for(int k=1;k<=h[i+1];++k){
g[l][r][k]=add(g[l][r][k],mul(sg[l][i][k],f[i+1][r][k]));
g[l][r][k]=add(g[l][r][k],mul(g[l][i][k],sf[i+1][r][k-1]));
}
}
for(int i=1;i<=n;++i){
sf[l][r][i]=add(sf[l][r][i-1],f[l][r][i]);
sg[l][r][i]=add(sg[l][r][i-1],g[l][r][i]);
}
}
}
printf("%lld\n",sg[1][n][n]);
return 0;
}
标签:ARC104F,题解,Visibility,节点,leq,quad,gets,sg,sf
From: https://www.cnblogs.com/BigSmall-En/p/16911832.html