1. 程式人生 > >[BZOJ4944/UOJ#316][NOI2017]泳池(概率DP+常係數齊次線性遞推)

[BZOJ4944/UOJ#316][NOI2017]泳池(概率DP+常係數齊次線性遞推)

Address

洛谷P3824
BZOJ4944
UOJ#316
LOJ#2304

Solution…

一、差分 容斥

要限制最大值恰好為一個定值往往是不好做的。
所以考慮容 (cha) 斥 (fen) ,把詢問 = K =K 拆成

K \le K K 1 \le K-1 ,這樣就轉化成了出現過的每一個安全子矩形
面積都不超過 K K (或不超過 K 1 K-1 )。
為了方便,下面我們只討論每一個安全子矩形面積都不超過 K
K
的求法。
(求 K \le K 和求 K 1 \le K-1 的方法大致相同,但是要特殊處理 0 \le 0 1 \le-1 的情況,否則在 UOJ 上會被 hack
0 \le 0 的答案為:
( 1 q ) n (1-q)^n
即最下面 n n 個格子全部不安全。
1 \le -1 的答案就不用解釋了,為 0 0

二、 g [ i ] [ j ] g[i][j] s [ i ] [ j ] s[i][j]

狀態 g [ i ] [ j ] g[i][j] 的定義為底邊長為 i i ,高為 1001 1001 ,最下面恰好 j j 行全部安全並且這個底邊長為 i i 高為 1001 1001 的矩形內不存在任意安全子矩形面積大於 K K 的概率。
s [ i ] [ j ] s[i][j] 表示底邊長為 i i ,高為 1001 1001 ,最下面至少 j j 行全部安全並且不存在任意安全子矩形面積大於 K K 的概率。相當於是 g [ i ] [ j ] g[i][j] 的字尾和。
a [ k ] a[k] 為第 k k 列的最下面有多少個安全的格子。
那麼顯然第 l l 列到第 r r 列內的最大安全子矩形為 r l + 1 r-l+1 乘上 a a 在區間 [ l , r ] [l,r] 內的最小值。
這涉及到所有區間的最小值,故可以採用笛卡爾樹的思想,找到最小值並向最小值的兩邊分治處理。
對於 g [ i ] [ j ] g[i][j] ,我們先列舉 k [ 0 , i 1 ] k\in[0,i-1] 表示 a a 最左的最小值在 k + 1 k+1 位置。顯然 a [ k + 1 ] a[k+1] 應該為 j j g g 的定義為最小值恰好為 j j )。
a [ 1 k ] a[1\dots k] 必須嚴格大於 a [ k + 1 ] a[k+1] j j (因為 a [ k + 1 ] a[k+1] 是最左的最小值),
s [ k ] [ j + 1 ] s[k][j+1]
a [ k + 2 i ] a[k+2\dots i] 必須大於等於 a [ k + 1 ] = j a[k+1]=j ,即 s [ i 1 k ] [ j ] s[i-1-k][j]
a [ k ] = j a[k]=j 的概率就是下面 j j 個格子全部安全而第 j + 1 j+1 個格子不安全的概率。
q j ( 1 q ) q^j(1-q)
得出轉移:
g [ i ] [ j ] = k = 0 i 1 q j × ( 1 q ) × s [ k ] [ j + 1 ] × s [ i 1 k ] [ j ] g[i][j]=\sum_{k=0}^{i-1}q^j\times(1-q)\times s[k][j+1]\times s[i-1-k][j]
s s g g 的字尾和:
s [ i ] [ j ] = s [ i ] [ j + 1 ] + g [ i ] [ j ] s[i][j]=s[i][j+1]+g[i][j]
邊界:
s [ 0 ] [ 0... K + 1 ] = 1 s[0][0...K+1]=1
複雜度:看上去是 O ( K 3 ) O(K^3) ,但是任何一個 g [ i ] [ j ] 0 g[i][j]\ne 0