模擬50 題解


A. 施工

又是利用了一些結論的題,因為想不到結論,經常做不出這種題。

枚舉兩個不變的邊界,那么中間的建築必定被提高成相同的小於等於邊界的高度。

於是設$f_i$表示考慮前i個建築,並且第i個建築高度不變的最優答案。

設對於轉移(i,j),中間建築的最優高度為t,可以寫出dp轉移方程。

拆開式子,可以得到一個二次函數。

直接求二次函數最值,可以做到$O(n^2)$。

接着發現很多的轉移是無效的,因為轉移(i,j)要滿足:

任取$i<k<j$,$h(k)<=h(i)$,$h(k)<=h(j)$。

可以維護一個由棧頂到棧底單調遞增的單調棧,以維護轉移的位置。

需要學習的是特殊的打法,用棧頂表示(i,j)范圍內最大的元素,而棧頂-1表示決策點。

 

 

 

B. 蔬菜

正解還是用到了分塊的思想:

1.對於出現次數很多的蔬菜,直接用前綴和累計答案。

2.對於出現次數較少的蔬菜,考慮將平方的含義轉化為點對。

將一棵蔬菜定義為點$(x,y)$,那么任意相同的兩棵蔬菜(可以是同一個棵)可以表示為點對$(x_1,x_2,y_1,y_2)$。

設詢問為$(x,y)(X,Y)$,即統計有多少個點對滿足:

限制(1):$x<=x_1<=X$  

限制(2):$x<=x_2<=X$

限制(3):$y<=y_1<=Y$  

限制(4):$y<=y_2<=Y$

四維偏序問題,可以暴力四維前綴和容斥。

然而空間復雜度$O(n^4)$,開不下。

考慮離線詢問,並且將每個詢問對於限制(1)拆為兩個,即$ans_X-ans_{x-1}$。

將所有點對按$x_1$排序,所有詢問按拆成的第一維限制排序。

那么對於每個詢問,單調指針不斷添加點對到三維數狀數組里,

添加完后大力三維容斥統計答案就可以了。

 

設蔬菜由出現次數決定使用哪種算法統計的分界值為k,

那么本題的復雜度為$O(n^2*\frac{n^2}{k})$(對每種大於k的蔬菜預處理)

+$O(n^2*k*log^3n)$(每種蔬菜都恰好接近k個的時候,總的點對最多,對這些點對的預處理)

+$O(q*(\frac{n^2}{k}+log^3n))$(每次詢問對於兩部分的查詢)

由均值不等式,可以得到當$k=\sqrt\frac{n^2+q}{log^3n}$時取得最優的復雜度。

 

另外記yxs巨神不用容斥的做法:

將每一個點對$(x_1,x_2,y_1,y_2)$化作點$(x_1,y_1)$在點$(x_2,y_2)$左上方的形式。

那么詢問的限制轉化為:

$x<=x_1$  $x_2<=X$

$y<=y_1$  $y_2<=Y$

因為$x_1$已經排序,自動滿足限制。

$x_2$,$y_2$都是小於等於某個值的限制,只要將$y_1$翻轉就可以直接查三維前綴和統計答案。

 

 

 

C. 聯盟

可以說是三道題里最簡單的一道。

首先,題中定義的危險程度,樹上最遠兩點距離,即樹的直徑。

那么問題被轉化成割掉樹上一條邊,求如何用一條邊連接兩棵樹使新樹的直徑最小。

顯然最優決策一定是連上兩棵新樹的直徑中點,因為任何改變位置都會使新樹的直徑更長。

於是問題轉化成如何求原樹上,割掉一條邊之后兩棵新樹的直徑。

正常的思路都是選節點1作為根節點,進行dfs求出子樹直徑。

然而問題是,有一些聯通塊無法被1的子樹表示出來。

那么考慮轉化思路,我們分別以樹上一條直徑的兩個端點作為根節點,求出子樹的直徑。

於是分類討論就可以了:

1.割掉非直徑邊:那么直徑所在聯通塊的直徑就是原樹的直徑,另一側的直徑可以被任意一個dp數組表示出來。

2.割掉直徑邊:那么兩個dp數組分別表示一個聯通塊的直徑。

最后隨便選一條符合的答案,抽出兩條直徑連中點就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM