在阅读本篇题解之前,请阅读 [USACO24JAN] Cowmpetency S 题解(或者洛谷博客链接)。
首先考虑一个 O(nc2) 的暴力 dp:设 fi,j 表示目前考虑 a 前 i 项,前缀 max=j 的方案数。转移方程显然:
fi,j←⎩⎪⎨⎪⎧j×fi−1,jj×fi−1,k(k≤j)j×fi−1,k(k<j)bi=−1bi=0bi=1
可以前缀和优化至 O(nc)。
我们发现,如果将 b 中连续的 0,−1 缩成一段,则段数是 O(q) 的,而连续的一段 0,−1 可以一起计算。设第 i 段元素为 bi,长度为 ci(当 bi=1 时 ci=1),fi,j 表示目前考虑前 i 段,前缀 max=j 的方案数。转移方程考虑讨论当前这一段是否出现了新的前缀最大值:
fi,j←jci×fi−1,j(bi=1)fi,j←gci(x)×fi−1,k(k<j,bi=−1)
其中 gy(x) 为 y 个 [1,x] 的整数至少有一个为 x 的方案数,用任意情况减去一个 x 都没有的情况可以推出 gy(x)=xy−(x−1)y。
可以前缀和优化至 O(qclogn),代码在这里。