[題解] 密碼 | 簡單計數


同步發表於 Mina!

題目大意

對於滿足以下要求的長度為 \(n\) 的序列進行計數:

  • 序列的值域為 \([1,k]\);

  • 對於序列的任意位置 \(p\in[1,n]\),可以找到至少一個 \(i\) 滿足 \(p\in[i,i+k-1]\),且區間 \([i,i+k-1]\) 為一個 \(1\sim k\) 的排列。

\(n\le10^5,k\le100\)

解題思路

其實原本題意不是這樣的,試圖描述正式之后好像更難懂了。

密碼是一個長度為 \(n\) 的序列。

密碼由若干個 \(1\sim k\) 的排列拼接而成,且拼接時,不同排列可重疊。

於是不妨設 \(f_i\) 為最后一個完整排列的結尾是 \(i\) 的方案數。於是可以列出轉移式:

\[f_i=\sum_{j=1}^{k}f_{i-j}\times g_{j} \]

\(g_j\) 即在一個 \(1\sim k\) 的排列后接上 \(j\) 個數,使得滿足以下兩個條件的方案數:

  • \([j+1,j+k]\) 是一個 \(1\sim k\) 的排列,

  • 對於任意 \(1<i<=j,[i,i+k-1]\) 不是一個 \(1\sim k\) 的排列。

直接拿 \(1,2,3\cdots k\) 來考慮 \(g_j\) 怎么求,那么即要求一個 \(1\sim j\) 的排列,對於任意 \(i<j\),這個排列 \([1,i]\) 的前綴位置上不能是一個 \(1\sim i\) 的排列,求滿足條件的排列個數。

考慮容斥,首先令 \(g_j=j!\),然后考慮減去不合法的,對於一個不合法的排列,它可能存在若干個前綴符合 \([1,i]\) 是一個 \(1\sim i\) 的排列,那么我們枚舉每一個不合法排列最后一個違反限制的前綴,在這個位置將其減去。

假設當前枚舉到 \(i\),首先 \([1,i]\) 這部分肯定是 \(i!\) 種填法,而 \([i+1,j]\) 這部分,由於我們欽定 \(i\) 是最后一個違反限制的前綴,故 \([1,i]\)\([i+1,j]\) 相接不可再違反限制,即對於任意 \(i<p<j,[i+1,p]\) 這一段上不能是將 \(i+1\sim p\) 這些數任意排列的結果,於是就變成子問題了,乘上 \(g_{j-i}\) 就好了。

所以就是兩個簡單的式子:

\[g_i=i!-\sum_{j=1}^{i-1}j!\times g_{i-j}\\ f_i=\sum_{j=1}^{k}f_{i-j}\times g_{j} \]

\(f_n\) 就是答案了,然后這個題大概還可以搞什么矩陣快速冪或者線性遞推,前者感覺沒必要,后者我不了解,於是就到此為止了 QwQ。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM