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\) 或 \(g\) 都可以,注意前 \(k+1\) 項需預處理,若 \(L\le k+1\) 就直接輸出。
不用寫任意模數乘法,直接暴力乘就行,這是 \(O(k^2\log L)\) 的,期望 100 pts.
這題可以稍微加強一下,以強迫你使用字首和最佳化,並且寫任意模數乘法。這是 \(O(k\log k\log L)\) 的。
因為目前各種板子都還沒打,所以暫時還沒有程式碼。