同步發表於 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\) 的方案數。於是可以列出轉移式:
\(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}\) 就好了。
所以就是兩個簡單的式子:
\(f_n\) 就是答案了,然后這個題大概還可以搞什么矩陣快速冪或者線性遞推,前者感覺沒必要,后者我不了解,於是就到此為止了 QwQ。