cpdeforces 712 E. Memory and Casinos 機率論 + 線段樹

給出一個數組p,長度爲n,1  <= n  <= 10^5數組

表示有n個格子,在第i個格子,你有p[i]的機率會到i + 1,有1 - p[i]的機率會到i - 1spa

若是在區間[l,r]上玩遊戲,咱們規定你起點在l,而後你開始走,遊戲

若是你到了l - 1,那麼你失敗了,遊戲結束query

若是你到了r + 1,那麼你成功了,遊戲結束

如今有q個操做,1 <= q <= 10^5

1 i a b   修改p[i] = (double)a / b

2 l r      詢問在[l,r]上玩遊戲,成功的機率

 

看這道題目,咱們首先反應就是線段樹,那要維護什麼?

咱們先來看看在[l,r]上玩遊戲,

令f(i)表示從i開始,到r + 1的機率,即遊戲成功的機率

咱們要求的就是f(l)

顯然,f(l - 1) = 0,f(r + 1) = 1

對l <= i <= r,f(i) = p[i] * f(i + 1) + (1 - p[i]) * f(i - 1)

則 f(i) - f(i - 1) = p[i] * f(i + 1) - p[i] * f(i - 1)

令g(i) = f(i) - f(i - 1)

(咱們要求f(l),因爲g(l) = f(l) - f(l - 1) = f(l),因此咱們要求的變成了g(l))

則g(i) = p[i] * (g(i + 1) + g(i))

令u[i] - (1 - p[i]) / p[i]

則g(i + 1) = u[i] * g(i)

發現g(l) + g(l + 1) + ... + g(r + 1) = 1

即g(l) = 1 / (1 + u[l] + u[l] * u[l + 1] + ... + u[l] * u[l + 1] * ... * u[r] )

因此,若是咱們用一顆線段樹,葉子節點i的值前綴積u[1] * u[2] * .. * u[i]

而後維護區間和

那麼對於每個詢問[l,r],要求g(l)

若是l = 1,g(l) = 1 / (1 + query(1,r,1,n,1))

若是l > 1,g(l) = query(l-1,l-1,1,n,1) / query(l-1,r,1,n,1)

而後修改操做在這裏就是區間修改了

能夠了

可是,這樣子會被卡精度,我就被卡了

怎麼改:

線段樹維護2個值,

若是一個節點表明的區間是[l,r]那麼這個節點維護

u[l] + u[l] * u[l + 1] + ... + u[l] * ... * u[r]  和

u[l] * ... * u[r]

那麼合併2個子節點也很簡單

同時修改操做成了單點修改啦

這樣子就能夠過了

相關文章
相關標籤/搜索