ABC221H

题面

link

​ 给定\(N,M(\le5\times 10^3)\),你需要对每一个\(k=1,2,..,N\),求出满足以下条件的可重集\(A\)的个数

  • \(A\)包含\(k\)个正整数,且\(\sum_{i=1}^kA_i=n\)
  • 同一元素的个数不超过\(M\)

题解

​ 想想暴力怎么写:设\(f[i][j]\)表示选了\(i\)个元素,和为\(j\),然后\(1\sim n\)枚举加入的元素,枚举加入的个数,再枚举状态来转移,这样是\(O(n^3\ln n)\)的。

​ 关键:为了避免重复,我们是从小到大枚举的元素,也就暗含了加入元素时递增的性质,这就启发了我们给这个递增的序列做差分。\(b_i=a_i-a_{i-1}\)

​ 这样的话,\(b_i\)的贡献就是\((k-i+1)b_i\),将序列翻转之后就是\(i\times b_i\),这样的话发现\(b_i\)的取值均摊下来只会有\(O(\ln)\)次(因为\(i\times b_i\)如果大于\(j\)就一定不会合法,可以直接break掉)

​ 所以,优化的效果达到了。我们再看一下现在的问题:你需要构造一个序列\(b_i\),满足没有连续\(M\)\(0\),并且最后一个数是正整数(即翻转前的\(b_1=a_1\))

​ 转移时我们可以枚举非\(0\)位置是谁,然后转移,具体来说

\[f[i][j]=\sum_{k=\max(1,i-m)}^{i-1}\sum_{p|i}f[k][j-p] \]

​ 然后用前缀和优化掉第一个sum。

启发

  • 把递增序列转化成差分序列,然后通过差分后序列会产生贡献的状态少了达到优化的效果!
  • 差分由于\(0\)的存在,经常会用到前缀和优化!
posted @ 2022-02-17 17:10  qwq_123  阅读(51)  评论(0编辑  收藏  举报