2019廈門ccpc J(點分治)

看到廈門的榜特別慘,比較好奇這套題。
題意:多組樣例,一顆帶有點權的無根樹,定義兩點路徑D爲其簡單路徑上的點的數量,定義MAX爲其路徑上的點權最大,MIN爲其路徑上的點權最小,現要你求最小的 D-MAX+MIN。 數據量總的節點數量,及最大點權均不超過10610^6

想了很久,看了一句話題解也只想到一個O(nlog2nlog2n)O(n*log_2n*log_2n)的做法,就是每次劃分子樹後,枚舉一顆子樹中的路徑,且枚舉過程中,記錄當前枚舉路徑的最大最小值

  1. 當前路徑可以作爲路徑最大值的端點,那麼就需要另一條路徑的端點作爲最小值,那麼就相當於在另一側中找最小值比當前路徑還要小的路徑中D+MIN的最小值。實現這個我們只需要實現一個可以維護前綴最小值的樹狀數組即可。
  2. 作爲最小值同理。維護後綴最小。

問了橘子貓大佬後,得到了一個O(nlog2n)O(n*log_2n)的做法!
注意到路徑的構成一定是 兩點的路徑點數-MAX+MIN。
那麼這裏我們只列舉枚舉路徑作爲最小值,最大值同理。
注意到 跨越重心的路徑可以拆解爲Dx+MINx+DyMAXyDx+MINx+Dy-MAXy
最開始看到那句話:“答案一定是那種最大值最小值作爲路徑端點的路徑”的時候有點困惑,沒太想清楚這裏要怎麼O(1)計算。
對於每條枚舉過的路徑,我們開一個變量MAXX來表示最小的DMAXD-MAX,這個直接對於每個路徑端點做更新就好,不必管他是不是路徑的最大值,因爲如果他不是路徑的最大值,那麼他必定小於已經存在的最大值,那麼必定他就不會使答案更優,也即不會更新MAXX,而如果他是當前路徑的最大值,那麼就可能更新MAXX。
並且我們枚舉路徑計算的時候,考慮兩種情況:

  1. MAXX中的最大值比枚舉路徑的最大值要小,那麼必然當我們下一次以當前子樹作爲重心劃分的時候會得到更優解。也即若當前答案被錯誤的更新了,後續也一定會被重新修正!
  2. MAXX中的最大值比枚舉路徑的最大值大,那麼就必定是一條合法的路徑,只要更新即可。

所以我們可以直接枚舉路徑,計算D+W[u]+MAXX1D+W[u]+MAXX-1

代碼暫時不貼,debug還沒完成

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章