【題解】HNOI2017 簡要題解
D1
面對數據編程情況下 270
單旋(樹狀數組)
發現每次splay的東西的都是最值。以最小值x伸展到根來舉例,這也就意味着rotate的時候一直沒得左子樹,那麼原樹的改動是
- \(fa[x]\)和\(rs[1][x]\) 連邊
- 除了\(rs[1][x]\)中的點,其他點深度++
其他操作也是一樣的。
聯繫BST \(T\)的性質,變化相同的點構成連續的區間,比如\(rs[1][x]\)中的點就是區間\((x,fa[x])\cap T\),其實這個\(\cap\)不用管他,因爲插入的時候清空就行了。
那麼維護每個點的fa和son,以及支持區間加單點查詢的樹狀數組就完事了
影魔(離線詢問枚舉端點)
還是樹狀數組(滑稽)
考慮第二檔分是什麼意思,\(2p_2=p_1\),就相當於"確定一個位置\(i\),再確定一段\(i\)爲端點的開區間,這個區間裏最大值是\(c\),如果\(c<p[i]\)就對答案+=\(p_2\)"。那麼每個點維護一個\(P_i,N_i\)分別表示上一個/下一個比他大數的位置,離線枚舉一次左端點枚舉一次右端點隨便做做就行了。
具體方法是維護一個隊列一個樹狀數組,對於沒有越過\(N\)的數\(i\)存到隊列中,那麼每個詢問在這個隊列裏找到最後一個位置\(\le r\)的下標,然後貢獻是下標\(\times\)區間長度。然後對於越過的情況,加到樹狀數組裏。每次詢問的時候也要查詢一下,注意這隻統計了\(i\)作爲右端點的情況,所以要枚舉兩次。
受到這檔分的啓發,考慮一個這樣的辦法,先假裝\(p_1=2p_2\),做一邊上述算法,然後令\(p_1=p_1-2p_2\),現在就是要數這個東西了。其實,假設現在枚舉到左端點\(l\),然後對於一個點\(x>l\),我們實際上就是要查詢\(\# i\in[l,x),N_i<x\),又是一個經典的二維偏序問題,也是離線枚舉一次右端點一次左端點就行了,具體操作同上,只是我們維護值域。
然後這個方法有點複雜,洛谷第一篇題解對詢問進行二位數點的高明多了。
禮物(FFT)
媽的我是sb
70pts做法
枚舉一下平移的長度,然後得到\(z_i=x_i-y_i\),這個情況的答案是\(\sum (z_i+c)\),化簡就是\(\sum z_i^2+2c\sum z +nc^2\),令\(c={-2\sum z\over n}\)取最近那個整數
正解:FFT
不想寫了,經典做法,我是sb
要上課了咕咕咕