6508. 【GDOI2020模擬03.11】我的朋友們

題目

有一個長度爲nn的數列aia_i,一開始將數列的前LL個丟入隊列中。
一次操作是對於隊列中的每個數aia_i,有aia_i的機率有11的貢獻。設貢獻和爲xx
然後將隊列中前xx個彈出去,再從數列中接着xx個。
如果數列中的數取完了,操作停止。
問期望進行多少次操作。


思考歷程

一開始就看錯了題意,於是這就變成的了一道神仙題。
只想到了aia_i相等的情況。
由於時間不夠,寫出來之後調都不調就交了。
結果自然是爆0。
(話說我在寫這個東西的時候沒有用分治NTT……不知道是我的方法錯了,還是確實能不用分治NTT……)


正解

fif_i爲當前隊列中的數在[i,i+L)[i,i+L)中的期望。
轉移十分顯然,這裏就不寫了。
直接暴力轉移肯定不能過,接下來就是在這個東西的基礎上優化。

把整個序列倒過來做,fif_i就變成了當前隊列中的數在(iL,i)(i-L,i)中的期望。
Pi=j=iL+1i(1aj+ajx)P_i=\prod_{j=i-L+1}^i (1-a_j+a_jx)
隨便推一推得:
fi=1+j=1Lfij[xj]Pi1[x0]P[i]f_i=\frac{1+\sum_{j=1}^Lf_{i-j}[x^j]P_i}{1-[x^0]P[i]}
接下來問題是處理j=1Lfij[xj]Pi\sum_{j=1}^Lf_{i-j}[x^j]P_i,其它的都很好辦。
Fi=j=LifjxjF_i=\sum_{j=L}^if_jx^j
於是j=1Lfij[xj]Pi=[xi](Fi1Pi)\sum_{j=1}^Lf_{i-j}[x^j]P_i=[x^i](F_{i-1}P_i)
這下就好看很多了。

考慮分治NTT。假如現在要計算區間[l,r][l,r]的答案。
對於每個i[l,r]i\in[l,r],我們把PiP_i的公因數提取出來,就是j=rL+1l(1aj+ajx)\prod_{j=r-L+1}^l(1-a_j+a_jx)
Fl,r=Fl1j=rL+1l(1aj+ajx)F_{l,r}^{'}=F_{l-1}\prod_{j=r-L+1}^l(1-a_j+a_jx),這就是前面[1,l1][1,l-1]區間對每一個i[l,r]i\in [l,r]共有的貢獻,可以一起算。
[xi]Fi,i[x^i]F_{i,i}^{'}就是對fif_i的貢獻。
考慮如何從Fl,rF_{l,r}^{'}轉移至Fl,midF_{l,mid}^{'}Fmid+1,rF_{mid+1,r}^{'}
Fl,mid=Fl1j=midL+1l(1aj+ajx)=Fl,rj=midL+1rL(1aj+ajx)F_{l,mid}^{'}=F_{l-1}\prod_{j=mid-L+1}^l(1-a_j+a_jx)\\=F_{l,r}^{'}\prod_{j=mid-L+1}^{r-L}(1-a_j+a_jx)
Fmid+1,r=Fmidj=rL+1mid+1(1aj+ajx)=Fl,rj=l+1mid+1(1aj+ajx)+(i=lmidfixi)j=rL+1mid+1(1aj+ajx)F_{mid+1,r}^{'}=F_{mid}\prod_{j=r-L+1}^{mid+1}(1-a_j+a_jx)\\=F_{l,r}^{'}\prod_{j=l+1}^{mid+1}(1-a_j+a_jx)+(\sum_{i=l}^{mid}f_ix^i)\prod_{j=r-L+1}^{mid+1}(1-a_j+a_jx)
上面式子中的那堆連乘都是可以用分治NTT預處理的。
看起來這個東西並沒有優秀到哪裏去啊……

我們想要求的,僅僅是[xi]Fi,i[x^i]F_{i,i}^{'}
對於Fl,rF_{l,r}^{'},如果它一直轉移到了葉子節點,那麼乘上的多項式的次數是O(rl)O(r-l)級別的。
我們最終只要對i[l,r]i\in [l,r]的所有ii有用的項,這意味着有些次數很小的項,他們次數增高O(rl)O(r-l)之後依然不會對任何i[l,r]i\in[l,r]ii產生影響,這個項就是沒用的。
對於沒用的項,那就可以忽略不計。
所以,只需要存最後O(rl)O(r-l)項就可以了。題解說標程存了最後2(rl+1)2(r-l+1)項。

於是這題就做完了,時間複雜度O(nlg2n)O(n \lg^2 n)


總結

一個晚上,兩個小時思考,再加一個小時寫博客整理思路。
這種到現在pty都沒有AC的題目,我不知道寫出來要多長時間。
就先把題解晾在這裏好了……

這題的精髓,除了亂推一波式子以外,我認爲是最後的那個保留最後幾項的那個操作。
我終於明白了原來分治NTT還能這麼搞。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章