P8735 蓝跳跳 题解

Statement

给出 \(k,p,L\),数序列 \(a\),满足如下条件:

  • \(1\le a_i\le k\)
  • \(\sum_i a_i=L\)
  • \(\nexists i,a_i\ge p\land a_{i+1}\ge p\)

答案对 \(20201114\) 取模,\(p\le k\le 1000, L\le 10^{18}\).

Solution

30 pts

注意到可以 dp,记 \(f(i,0/1)\) 为凑出 \(i\) 的方案数,其中最后一个数是否 \(<p\).

\[ \begin{aligned} f(i,1)&=\sum_{1\le j<p} f(i-j,1)+f(i-j,0)\\ f(i,0)&=\sum_{p\le j\le k} f(i-j,1)\\ f(0,1)&=1 \end{aligned} \]

答案为 \(f(L,0)+f(L,1)\),时间 \(O(kl)\),预计得分 30 pts.

我做了个没什么用的前缀和优化:记 \(g(i,0/1)\)\(f(i,0/1)\) 的前缀和,推式子可得

\[ \begin{aligned} g(i,0)&=g(i-1,0)+g(i-p,1)-g(i-k-1,1)\\ g(i,1)&=2g(i-1,1)+g(i-1,0)-g(i-p,1)-g(i-p,0)\\ g(0,1)&=1 \end{aligned} \]

答案为 \(g(L,0)-g(L-1,0)+g(L,1)-g(L-1,1)\),时间 \(O(L)\),预计得分 30 pts.

60 pts

用矩阵快速幂优化上述 dp,\(f\)\(g\) 都可以,时间 \(O(k^3\log L)\),带有 8 倍常数,预计得分 60 pts.

100 pts

考虑把 \(f(i,0)\) 拆成若干 \(f(i,1)\),这样就可以线性递推了!

不用写任意模数乘法,直接暴力乘就行,预处理系数也可以直接暴力,这是 \(O(k^2\log L)\) 的,期望 100 pts.

也可以用 \(g\) 算,把 \(g(i,0)\) 拆成若干 \(g(i,1)\) 就行了,预处理系数时会更优一点,需要稍微推一下式子。

你当然可以再写一个任意模数乘法做到 \(O(k\log k\log L)\)

因为目前各种板子都还没打,所以暂时还没有代码。

posted @ 2024-08-17 14:04  Laijinyi  阅读(7)  评论(0编辑  收藏  举报