1. 程式人生 > 實用技巧 >Grammy's Restaurant

Grammy's Restaurant

連結

題目大意

給定 \(m\) 個區間,有 \(n\) 次詢問,每次給定 \(k_i\) 個點(\(\sum{k_i}\leq 10^5\)),問 \(m\) 區間 \([l_j,r_j]\) 中,將區間中的所有點排序後 \(r_j-l_j+\sum{i\times a_i}\) 的最大值。這裡 \(i\) 表示排序後的位置。

題解

考慮一個性質:如果一個區間包含另一個區間,那麼被包含的區間無論如何都不會最優。

將這些區間去掉,同時將剩下區間按左端點排序,可以發現右端點也是單調遞增的。

接下來再考慮一個性質:將 \(a_i\) 從小到大排序後,如果某些區間都只包含了同一段 \(a_i\),那麼取最長的區間最優。

這個其實很明顯,因為價值中關於 \(a_i\) 的部分只要被區間覆蓋,就與區間的其他部分無關。所以只需長度最大即可。

很顯然找到覆蓋一個區間的最長區間本質就是一個二維數點的變型(求某個矩形中的最大值),怎麼寫都行。

那麼接下來問題就是找到最優的 \(a_i\) 被覆蓋區間是那一段。

首先有一個特別顯然的雙指標的演算法,即每次固定左端點 \(a_l\),向右找到最遠一個能夠被某個區間包含的 \(a_r\),然後再將左端點向右移動一步,繼續移動右端點。

但是這個貪心其實是有問題的。考慮這個例子:

1 2
1 100 2 100000
4 1 2 3 100001


(上述黃點表示 \(a_i\),藍線表示區間)

可以發現這種情況下,首先雙指標會掃到 \(a_1,a_2,a_3\)

區間,然後再掃到 \(a_1\)~\(a_4\),發現此時沒有區間符合,然後就掃 \(a_2\)~\(a_4\),發現還是沒有區間符合。於是最優解第二個區間包含的 \(a_2\)~\(a_3\) 就被跳過了。

所以考慮二分:雖然區域性最優解的位置隨 \(a_l\) 移動不是單調遞增的,但是固定 \(a_l\) 後最優解 \(a_r\) 的位置是可二分的,因為顯然假如一個區間包含了 \(a_l\)~\(a_r\),那麼顯然也包含了 \(a_l\)~\(a_{r-1}\)。所以滿足可二分性。

然後直接查詢時間複雜度 \(O(n\log^2 n)\),用ST表優化後可以達到 \(O(n\log n)\)